題面大意:有一個01序列,改變一個位置上的值花費1,問變成沒有0在1右邊的序列花費最少多少c++
直接枚舉前i個都變成0便可spa
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define eps 1e-10 #define MAXN 200005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; 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; char s[MAXN]; int sum[MAXN]; void Solve() { read(N); scanf("%s",s + 1); for(int i = 1 ; i <= N ; ++i) { sum[i] = sum[i - 1]; if(s[i] == '#') sum[i]++; } int ans = N; for(int i = 0 ; i <= N ; ++i) { ans = min(ans,sum[i] + N - i - (sum[N] - sum[i])); } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
大意:將數分到三個標號爲123的集合,要求三個集合能構成三角形code
題解:也就是\(R + B + G = S\)知足\(G,R,B < \frac{S}{2}\)three
不合法的狀況就是有一個集合大於等於\(\frac{S}{2}\)的方案,對於等於\(\frac{S}{2}\)再用一個dp去重便可get
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define eps 1e-10 #define MAXN 200005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; 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); } const int MOD = 998244353; int N; int a[305],S; int dp[305][90005],f[90005]; int inc(int a,int b) { return a + b >= MOD ? a + b - MOD : a + b; } int mul(int a,int b) { return 1LL * a * b % MOD; } void update(int &x,int y) { x = inc(x,y); } 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() { read(N); for(int i = 1 ; i <= N ; ++i) { read(a[i]); S += a[i]; } dp[0][0] = 1; f[0] = 1; for(int i = 1 ; i <= N ; ++i) { for(int j = S ; j >= 0 ; --j) { update(dp[i][j],mul(2,dp[i - 1][j])); if(j >= a[i]) { update(dp[i][j],dp[i - 1][j - a[i]]); update(f[j],f[j - a[i]]); } } } int ans = fpow(3,N); for(int j = 0 ; j <= S ; ++j) { if(j * 2 >= S) { update(ans,MOD - mul(3,dp[N][j])); } } if(S % 2 == 0) { update(ans,mul(f[S / 2],3)); } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
大意:給定多項式求多項式取全部整數值時都能被整除的質數it
盲猜確定要麼是全部係數的gcd的質因數要麼就小於最高次項,而後判解不會就直接暴力,覺得數據造不滿而後被卡死了,atc的數據仍是強class
事實上判解的話只要判這個多項式在modp意義下是不是多項式\(x^{p} - x\)的倍數便可test
充分性顯然(費馬小定理)date
必要性合法的式子會含有\(x(x - 1)(x - 2)..(x - (p - 1))\),而後這個東西在modp意義下是\(x^{p} - x\)相等,若是不是全等的話,必然有一個小於等於p - 1的多項式是有p個根,這不存在gc
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define eps 1e-10 #define MAXN 10005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; 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); } set<int> S; int g; int N,a[MAXN],b[MAXN],c[MAXN]; int prime[MAXN],tot; bool nonprime[MAXN]; int gcd(int a,int b) { return b == 0 ? a : gcd(b,a % b); } void Solve() { read(N); for(int i = N ; i >= 0 ; --i) { read(a[i]); g = gcd(g,abs(a[i])); } for(int i = 2 ; i <= g / i ; ++i) { if(g % i == 0) { S.insert(i); while(g % i == 0) g /= i; } } if(g > 1) S.insert(g); for(int i = 2 ; i <= 10000 ; ++i) { if(!nonprime[i]) { prime[++tot] = i; } for(int j = 1 ; j <= tot ; ++j) { if(1LL * i * prime[j] > 10000) break; nonprime[i * prime[j]] = 1; if(i % prime[j] == 0) break; } } for(int i = 1 ; i <= tot ; ++i) { if(prime[i] > N) break; int p = prime[i]; if(S.find(p) != S.end()) continue; memset(b,0,sizeof(b)); memset(c,0,sizeof(c)); bool flag = 1; for(int i = N ; i >= 0 ; --i) { b[i] = (a[i] + c[i]) % p; if(i >= p) { c[1 + i - p] += b[i]; c[1 + i - p] %= p; } else if(b[i]){ flag = 0;break; } } if(flag) S.insert(p); } for(auto t : S) { out(t);enter; } } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }
大意:找到一個長度爲N序列只含0,1,2,求其中任意一段連續的和不爲x的答案
首先統計全部和小於x的答案
而後就是若是x爲奇數,我只選2且序列總和大於x的答案
而後就是,由於我每一段的和都不是x,每次增長是1或2,那麼確定存在一個和是\(X - 1\)的前綴和
此時我只能選2,若是序列開頭第一個不爲0的數是2,那麼我能夠刪掉這個2,日後繼續加一個2,直到我刪掉時遇到了一個1
因此咱們枚舉i個2+1個1的序列,枚舉構成X - 1所用的序列長度,以後只能日後加不超過i個2便可
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define eps 1e-10 #define MAXN 10005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; 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); } const int MOD = 998244353; int N,X; int dp[3005][6005],fac[6005],invfac[6005]; int f[3005]; int inc(int a,int b) { return a + b >= MOD ? a + b - MOD : a + b; } int mul(int a,int b) { return 1LL * a * b % MOD; } void update(int &x,int y) { x = inc(x,y); } 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; } int C(int n,int m) { if(n < m) return 0; return mul(fac[n],mul(invfac[m],invfac[n - m])); } void Solve() { read(N);read(X); dp[0][0] = 1; fac[0] = 1; for(int i = 1 ; i <= 2 * N ; ++i) fac[i] = mul(fac[i - 1],i); invfac[2 * N] = fpow(fac[2 * N],MOD - 2); for(int i = 2 * N - 1 ; i >= 0 ; --i) { invfac[i] = mul(invfac[i + 1],i + 1); } int ans = 0; for(int i = 1 ; i <= N ; ++i) { for(int j = 2 * i ; j >= 1 ; --j) { if(j >= 2) update(dp[i][j],dp[i - 1][j - 2]); if(j >= 1) update(dp[i][j],dp[i - 1][j - 1]); } } for(int i = 0 ; i <= N ; ++i) { for(int j = 0 ; j <= 2 * i ; ++j) { if(j < X) update(ans,mul(dp[i][j],C(N,i))); } } for(int i = 1 ; i < N ; ++i) { int t = i * 2 + 1; if(t >= X) break; for(int j = 0 ; j <= N ; ++j) { if(i + j + 2 <= N) { update(f[i + j + 2],dp[j][X - 1 - t]); if(i + j + i + 2 <= N) update(f[i + j + i + 2],MOD - dp[j][X - 1 - t]); } } } for(int i = 1 ; i <= N ; ++i) f[i] = inc(f[i],f[i - 1]); for(int i = 1 ; i <= N ; ++i) { update(ans,mul(f[i],C(N,i))); } if(X & 1) { for(int i = 1 ; i <= N ; ++i) { if(i * 2 > X) update(ans,C(N,i)); } } out(ans);enter; } int main() { #ifdef ivorysi freopen("f1.in","r",stdin); #endif Solve(); }