每次操做必然包含一个1
枚举第一次操做的位置计算两边便可node
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define space putchar(' ') #define enter putchar('\n') #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; template<class T> void read(T &res) { res = 0;T f = 1;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; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) out(x / 10); putchar('0' + x % 10); } int N,K; int a[MAXN],pos[MAXN]; int C(int x) { return x % (K - 1) == 0 ? x / (K - 1) : x / (K - 1) + 1; } void Solve() { read(N);read(K); for(int i = 1 ; i <= N ; ++i) {read(a[i]);pos[a[i]] = i;} int ans = N; for(int i = 1 ; i <= N ; ++i) { if(i + K - 1 >= pos[1]) { ans = min(ans,C(i - 1) + C(N - min((i + K - 1),N)) + 1); } } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
咱们对于N 只要能求出\(f(N + 1)\)(\(f(x)\)表示大于等于\(x\)的数中\(\frac{x}{S(x)}\)最小的那个)
那么就能不断找到下一个数了ios
怎么求呢,咱们能够认为一个能够被取到的数必定是x的一段前缀,加上中间某个数修改,后面的全部数都改为9c++
由于999999...9999是一个合法的数,那么能够认为\(f(x)\)的位数和\(x\)必定相同数组
若是咱们找到一个数\(a\),它的第d位与x不一样,且它后面不都是9,那么咱们能够把第d位-1,后面所有修改为9spa
因此咱们找的数的数目有限,都找出来找最小的\(\frac{x}{S(x)}\)便可code
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define space putchar(' ') #define enter putchar('\n') #define MAXN 100005 //#define ivorysi using namespace std; typedef long long int64; template<class T> void read(T &res) { res = 0;T f = 1;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; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) out(x / 10); putchar('0' + x % 10); } int K,t[25],tot,cnt,s[10005]; int64 L[10005],p[25],b[25]; int S(int64 x) { int res = 0; while(x) {res += x % 10;x /= 10;} return res; } int64 f(int64 x) { tot = 0;cnt = 0;int64 h = x; while(h) {t[++tot] = h % 10;h /= 10;} int64 num = 0; for(int i = tot ; i >= 1 ; --i) { for(int j = t[i] ; j <= 9 ; ++j) { int64 tmp = num + j * b[i - 1] + p[i - 1]; if(tmp >= x) L[++cnt] = tmp; } num = num + t[i] * b[i - 1]; } for(int i = 1 ; i <= cnt ; ++i) s[i] = S(L[i]); int r = 1; for(int i = 2 ; i <= cnt ; ++i) { int64 h = L[i] * s[r] - L[r] * s[i]; if(h < 0) r = i; else if(h == 0 && L[i] < L[r]) r = i; } return L[r]; } void Solve() { read(K); int64 N = 1; p[1] = 9; for(int i = 2 ; i <= 16 ; ++i) p[i] = p[i - 1] * 10 + 9; b[0] = 1; for(int i = 1 ; i <= 16 ; ++i) b[i] = b[i - 1] * 10; while(K--) { out(N);enter; N = f(N + 1); } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
反图必然是个二分图,否则则无解get
咱们但愿知道哪些分的状况能够达到,就直接把一个二分图的联通块拿出来,作分组背包便可string
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define space putchar(' ') #define enter putchar('\n') #define MAXN 100005 #define mp make_pair //#define ivorysi using namespace std; typedef long long int64; template<class T> void read(T &res) { res = 0;T f = 1;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; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) out(x / 10); putchar('0' + x % 10); } int N,M; int g[705][705]; struct node { int to,next; }E[1000005]; int sumE,head[705],tot,col[705],que[705],qr; pii conn[705]; bool f[2][705]; void add(int u,int v) { E[++sumE].next = head[u]; E[sumE].to = v; head[u] = sumE; } bool dfs(int u) { if(col[u] == -1) col[u] = 0; que[++qr] = u; for(int i = head[u] ; i ; i = E[i].next) { int v = E[i].to; if(col[v] == col[u]) return false; else if(col[v] == -1) { col[v] = col[u] ^ 1; if(!dfs(v)) return false; } } return true; } void Solve() { read(N);read(M); int u,v; for(int i = 1 ; i <= M ; ++i) { read(u);read(v); g[u][v] = g[v][u] = 1; } for(int i = 1 ; i <= N ; ++i) { for(int j = i + 1 ; j <= N ; ++j) { if(!g[i][j]) {add(i,j);add(j,i);} } } memset(col,-1,sizeof(col)); for(int i = 1 ; i <= N ; ++i) { if(col[i] == -1) { qr = 0; if(!dfs(i)) {puts("-1");return;} int cnt[2] = {0,0}; for(int j = 1 ; j <= qr ; ++j) cnt[col[que[j]]]++; conn[++tot] = mp(cnt[0],cnt[1]); } } int cur = 0; f[0][0] = 1; for(int i = 1 ; i <= tot ; ++i) { memset(f[cur ^ 1],0,sizeof(f[cur ^ 1])); for(int j = N ; j >= 0 ; --j) { if(j >= conn[i].fi) f[cur ^ 1][j] |= f[cur][j - conn[i].fi]; if(j >= conn[i].se) f[cur ^ 1][j] |= f[cur][j - conn[i].se]; } cur ^= 1; } int ans = N * N; for(int i = 0 ; i <= N ; ++i) { if(f[cur][i]) { ans = min(i * (i - 1) / 2 + (N - i) * (N - i - 1) / 2,ans); } } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
一道神奇的题it
咱们把操做S构成的A数组用一个多项式表示出来
\(t(S) = \sum_{i = -10^9}^{10^9} A_{i}X^{i}\)
若是往S前面添加一个字符的话
\(t<(S) = t(S)X^{-1}\)
\(t>(S) = t(S)X\)
\(t+(S) = t(S) + 1\)
\(t-(S) = t(S) - 1\)
那么咱们对于最终的序列求一个哈希值c,若是一段区间操做后的结果和c同样的话就有
\(t_{S_i}t_{S_{i + 1}}...t_{S_j}(0) = c\)
因为这些操做可逆,能够一层一层拆开
能够获得
\(t_{S_N}^{-1}...t_{S_i}^{-1}t_{S_i}t_{S_{i + 1}}...t_{S_j}(0) = t_{S_N}^{-1}...t_{S_i}^{-1}(c)\)
那么咱们能够获得
\(t_{S_N}^{-1}...t_{S_{j + 1}}^{-1} (0) = t_{S_N}^{-1}...t_{S_{i}}^{-1}(c)\)
这个后缀积能够线性处理出来,维护未知数前的系数便可io
而后就是愉快的用map查询了
那么,冲突怎么考虑?题解说是冲突的几率在2N/模数大小,让用6个,然而我写的不优美,T掉了,改为5个卡着时限A了,感受用不上太多也是对的啊
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <queue> #include <cmath> #include <map> #define enter putchar('\n') #define space putchar(' ') #define mp make_pair #define pb push_back #define fi first #define se second #define pii pair<int,int> #define eps 1e-7 #define MAXN 250005 #define MOD 999999137 //#define ivorysi using namespace std; typedef long long int64; typedef double db; typedef vector<int> poly; template<class T> void read(T &res) { res = 0;char c = getchar();T f = 1; 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; } template<class T> void out(T x) { if(x < 0) {putchar('-');x = -x;} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } int B[] = {0,823,727,401,271,571}; int InvB[10]; int f[8][MAXN],g[8][MAXN],N,h[8][MAXN]; char s[MAXN]; map<int,int> MK[8]; int mul(int a,int b) { return 1LL * a * b % MOD; } int inc(int a,int b) { return a + b >= MOD ? a + b - MOD : a + b; } void update(int &x,char c,int id) { if(c == '<') x = mul(x,InvB[id]); else if(c == '>') x = mul(x,B[id]); else if(c == '+') x = inc(x,1); else x = inc(x,MOD - 1); } int fpow(int x,int c) { int res = 1,t = x; while(c) { if(c & 1) res = mul(res,t); t = mul(t,t); c >>= 1; } return res; } void Solve() { for(int i = 1 ; i <= 5 ; ++i) InvB[i] = fpow(B[i],MOD - 2); read(N); scanf("%s",s + 1); int c[10] = {0}; for(int k = 1 ; k <= 5 ; ++k) { for(int i = N ; i >= 1 ; --i) { update(c[k],s[i],k); } } for(int k = 1 ; k <= 5 ; ++k) h[k][N + 1] = 1,g[k][N + 1] = c[k],MK[k][0] += 1; int64 ans = 0; for(int i = N ; i >= 1 ; --i) { int add = N - i + 1; for(int k = 1 ; k <= 5 ; ++k) { if(s[i] == '<') { g[k][i] = inc(g[k][i + 1],MOD - mul(h[k][i + 1],c[k])); h[k][i] = mul(h[k][i + 1],B[k]); g[k][i] = inc(g[k][i],mul(h[k][i],c[k])); f[k][i] = f[k][i + 1]; } else if(s[i] == '>') { g[k][i] = inc(g[k][i + 1],MOD - mul(h[k][i + 1],c[k])); h[k][i] = mul(h[k][i + 1],InvB[k]); g[k][i] = inc(g[k][i],mul(h[k][i],c[k])); f[k][i] = f[k][i + 1]; } else if(s[i] == '+') { h[k][i] = h[k][i + 1]; g[k][i] = inc(g[k][i + 1],MOD - h[k][i]); f[k][i] = inc(f[k][i + 1],MOD - h[k][i]); } else { h[k][i] = h[k][i + 1]; g[k][i] = inc(g[k][i + 1],h[k][i]); f[k][i] = inc(f[k][i + 1],h[k][i]); } add = min(add,MK[k][g[k][i]]); MK[k][f[k][i]] += 1; } ans += add; } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); return 0; }