比赛入口
B Infinite Prefixes
做法:卡了好久啊…其实就两种情况嘛,一种就是a[n]=0,这时候如果a[i]=x,答案就是-1了,反之结果就是0了,去掉这种情况后,只要满足(x - a[i]) % a[n] == 0且(x - a[i]) 与a[n]同号,答案就+1即可…
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int N = 1e5+5;
int a[N];
char s[N];
int main() {
int t; read(t);
int n, x, len;
while(t--) {
scanf("%d%d%s", &n, &x, s+1);
len = strlen(s+1);
int res = a[0] == x, cnt0 = 0;
for(int i = 1; i <= len; ++i) {
a[i] = a[i-1] + (s[i] == '1' ? -1 : 1);
if(a[i] == x) ++res;
}
if(!a[len]) {
puts(res ? "-1" : "0");
} else {
int ans = 0;
for(int i = 1; i <= len; ++i) {
if((x - a[i]) % a[len] == 0 && (x - a[i]) / a[len] >= 0) ans++;
}
if(!x) ans++;
printf("%d\n", ans);
}
}
return 0;
}
C Obtain The String
做法:用序列自动机直接找位置就好了0.0
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int N = 1e5+5;
char s[N], t[N];
vector<int> ve[26];
int main() {
int T; read(T);
int lens, lent;
while(T--) {
scanf("%s%s", s, t);
lens = strlen(s); lent = strlen(t);
for(int i = 0; i < 26; ++i) ve[i].clear();
for(int i = 0; i < lens; ++i) ve[s[i]-'a'].push_back(i);
int f = 1, ans = 1, mid = -1, mid1;
for(int i = 0; i < lent; ++i) {
mid1 = t[i]-'a';
if(ve[mid1].empty()) {
f = 0; break;
} else {
int pos = upper_bound(ve[mid1].begin(), ve[mid1].end(), mid) - ve[mid1].begin();
if(pos == ve[mid1].size()) {
mid = -1, ans++;
pos = upper_bound(ve[mid1].begin(), ve[mid1].end(), mid) - ve[mid1].begin();
}
mid = ve[mid1][pos];
}
}
if(!f) puts("-1");
else printf("%d\n", ans);
}
return 0;
}
E Permutation Separation
做法:线段树区间加法和区间维护最小值?(雾)
代码:
#include<bits/stdc++.h>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define lson rt<<1, l, mid
#define rson rt<<1|1, mid+1, r
using namespace std;
typedef long long LL;
typedef pair<LL, int> pli;
typedef pair<int, int> pii;
typedef pair<LL, LL> pll;
typedef pair<double, double> pdd;
typedef map<char, int> mci;
typedef map<string, int> msi;
template<class T>
void read(T &res) {
int f = 1; res = 0;
char c = getchar();
while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); }
while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); }
res *= f;
}
const int N = 2e5+ 10;
int n;
int a[N], p[N];
LL tr[N<<2], tag[N<<2];
void Add(int rt, LL d) {
tag[rt] += d; tr[rt] += d;
}
void pushdown(int rt) {
if(tag[rt]) {
Add(rt<<1, tag[rt]);
Add(rt<<1|1, tag[rt]);
tag[rt] = 0;
}
}
void modify(int rt, int l, int r, int L, int R, int d) {
if(L <= l && r <= R) {
Add(rt, d); return ;
}
int mid = (l + r) >> 1;
pushdown(rt);
if(L <= mid) modify(lson, L, R, d);
if(R > mid) modify(rson, L, R, d);
tr[rt] = min(tr[rt<<1], tr[rt<<1|1]);
}
int main() {
read(n);
for(int i = 1; i <= n; ++i) read(p[i]);
for(int i = 1; i <= n; ++i) read(a[i]);
for(int i = 1; i <= n; ++i)
modify(1, 0, n, p[i], n, a[i]);
LL ans = 1e18;
for(int i = 1; i < n; ++i) {
modify(1, 0, n, p[i], n, -a[i]);
modify(1, 0, n, 0, p[i]-1, a[i]);
ans = min(ans, tr[1]);
}
printf("%lld\n", ans);
return 0;
}
F Good Contest
做法:貌似是day6的D题弱化版…(雾×10086)