2017年百度之星部分题解
初赛A
小C的倍数问题 p-1因子个数
#include <bits/stdc++.h> const long long mod = 1e9+7; const double ex = 1e-10; #define inf 0x3f3f3f3f using namespace std; int main() { int T; cin >> T; while (T--){ long long x; cin >> x; long long ans = 0; for (long long i = 1LL; i*i<x;i++){ if ((x-1) % i == 0) ans+=2; if (i*i == x-1) ans--; } cout << ans <<endl; } return 0; }
今夕何夕 模拟
#include <bits/stdc++.h> const long long mod = 1e9+7; const double ex = 1e-10; #define inf 0x3f3f3f3f using namespace std; string s[105]; int main() { int T; cin >> T; while (T--){ int y,m,d,c,g=0; int x = 0; scanf("%d-%d-%d",&y,&m,&d); if (m==1||m==2){ m += 12; y--; g = 1; } int ty = y; c = (y)/100; y=y-100*c; x = ((y+y/4+c/4-2*c+26*(m+1)/10 + d - 1 + 7) % 7 + 7 ) % 7; int flag = 0; if ((((ty+1)%4==0&&(ty+1)%100!=0)||(ty+1)%400==0)&&(m==14&&d==29)) flag = 4; else flag = 1; int tx = 0; for (int i = ty+flag; i<=9999;i+=flag){ c = (i)/100; y=i-100*c; if ((flag == 4)&&!((((i+1)%4==0&&(i+1)%100!=0)||(i+1)%400==0))) continue; tx = ((y+y/4+c/4-2*c+26*(m+1)/10 + d - 1 + 7) % 7 + 7 ) % 7; if (tx == x){ cout<<i+g<<endl; break; } } } return 0; }
度度熊的01世界 暴力dfs
#include <bits/stdc++.h> const long long mod = 1e9+7; const double ex = 1e-10; #define inf 0x3f3f3f3f using namespace std; string s; int pic[110][110]; int vis[110][110]; int cnt[3]; int tx[4] = {0,0,1,-1}; int ty[4] = {1,-1,0,0}; int n,m; void dfs(int x,int y,int t){ if (x<0||y<0||x>n+1||y>m+1) return; if (pic[x][y]!=t) return; if (vis[x][y]) return; vis[x][y] = 1; for (int i = 0; i<4; i++) dfs(x+tx[i],y+ty[i],t); return; } int main() { while (cin >> n >>m){ memset(vis,0,sizeof(vis)); for (int i = 0; i<=m+1;i++) pic[0][i] = pic[n+1][i] = 0; for (int i = 1; i<=n;i++){ cin >> s; pic[i][0] = pic[i][m+1] = 0; for (int j = 1; j<=m;j++) pic[i][j] = s[j-1] - '0'; } cnt[1] = cnt[0] = 0; for (int i = 0;i<=n+1; i++){ for (int j = 0; j<=m+1; j++){ if(vis[i][j] == 0 ){ dfs(i,j,pic[i][j]); cnt[pic[i][j]]++; } } } if (cnt[1] == 1 && cnt[0] == 1) puts("1"); else if (cnt[1] == 1 &&cnt[0] == 2) puts("0"); else puts("-1"); } return 0; }
初赛B
Chess 简单组合数
#include <bits/stdc++.h> const long long mod = 1e9+7; const double ex = 1e-10; #define inf 0x3f3f3f3f using namespace std;\ const long long N = 1000 + 5; const long long MOD = (long long)1e9 + 7; long long F[N], Finv[N], inv[N];//F是阶乘,Finv是逆元的阶乘 void init(){ inv[1] = 1; for(long long i = 2; i < N; i ++){ inv[i] = (MOD - MOD / i) * 1ll * inv[MOD % i] % MOD; } F[0] = Finv[0] = 1; for(long long i = 1; i < N; i ++){ F[i] = F[i-1] * 1ll * i % MOD; Finv[i] = Finv[i-1] * 1ll * inv[i] % MOD; } } long long C(int n, int m){ if(m < 0 || m > n) return 0; return F[n] * 1ll * Finv[n - m] % MOD * Finv[m] % MOD; } int main() { int T; cin >> T; init(); while (T--){ int N,M; cin >> N >> M; cout << C(max(N,M),min(N,M))<<endl; } }
度度熊的交易计划 最小费用可行流
#include <iostream> #include <cstdio> #include <algorithm> #include <queue> #include <cstring> #define INF 0x3f3f3f3f using namespace std; struct edge{ int from,to,cap,cost,next; }E[160000]; int tot; int head[600];int dis[600]; int inq[600]; int pre[600]; int maxf = 0; int n,m; void addedge(int a,int b,int cap, int cost) { E[tot].from = a; E[tot].to = b; E[tot].cap = cap; E[tot].cost = cost; E[tot].next = head[a]; head[a] = tot++; //反向边 E[tot].from = b; E[tot].to = a; E[tot].cap = 0; E[tot].cost = -cost; E[tot].next = head[b]; head[b] = tot++; } void init(){ for (int i = 1; i<=n;i++){ int a,b,c,d; scanf("%d%d%d%d",&a,&b,&c,&d); addedge(n+1,i,b,a); addedge(i,n+2,d,-c); } for (int i = 1; i<=m;i++){ int u,v,k; scanf("%d%d%d",&u,&v,&k); if (u==v) continue; addedge(u,v,INF,k); addedge(v,u,INF,k); } } void initfirst() { memset(E,0,sizeof(E)); memset(head,-1,sizeof(head)); memset(pre,-1,sizeof(pre)); tot = 0; maxf = 0; }bool spfa(int b , int e) { memset(dis,INF,sizeof(dis)); memset(inq,false,sizeof(inq)); memset(pre, -1, sizeof(pre)); queue<int> q; dis[b] = 0; inq[b] = true; q.push(b); while (!q.empty()) { int u = q.front() ;q.pop(); for (int i = head[u]; i!=-1 ; i = E[i].next) { int v = E[i].to; if (E[i].cap && dis[v] > dis[u] + E[i].cost) { dis[v] = dis[u] + E[i].cost; pre[v] = i; if (!inq[v]) {q.push(v);inq[v] = true;} } } inq[u] = false; } if (dis[e]>=0) return false; else return pre[e]!=-1; } int MCMF(int b ,int e) { int ANS = 0; while (spfa(b,e)) { int minf = INF; for (int i = e ; i!=b ; i = E[pre[i]].from) { minf = min(minf , E[pre[i]].cap); } for (int i = e ; i!=b ; i = E[pre[i]].from) { E[pre[i]].cap -= minf; E[pre[i]^1].cap += minf; } maxf += minf; ANS += (minf*dis[e]); } return ANS; } int main() { while (cin >> n >> m){ initfirst(); init(); int ans = MCMF(n+1,n+2); cout << -ans << endl; } }
小小粉丝度度熊 傻逼双指针,傻逼数据有负数,艹TMGBD。
#include <bits/stdc++.h> const long long mod = 1e9+7; const double ex = 1e-10; #define inf 0x3f3f3f3f using namespace std; struct node{ int l,r; }E[100011],G[100011]; int N; int M; bool cmp(node a,node b){ if (a.l == b.l) return a.r < b.r; else return a.l < b.l; } int main() { while (scanf("%d%d",&N,&M)==2){ memset(E,0,sizeof(E)); memset(G,0,sizeof(G)); for (int i = 1; i<=N; i++) scanf("%d%d",&E[i].l,&E[i].r); sort(E+1,E+N+1,cmp); int nowL=E[1].l,nowR=E[1].r; int cnt=0; for(int i=2;i<=N;i++) { if(nowR<E[i].l) { G[++cnt]=node{nowL,nowR}; nowL=E[i].l; nowR=E[i].r; } else if(nowR<E[i].r) nowR=E[i].r; } G[++cnt]=node{nowL,nowR}; /* int cnt = 0; G[0].r = G[0].l = -1; for (int i = 1; i<=N; i++){ if (E[i].l <= G[cnt].r+1) G[cnt].r = max(E[i].r,G[cnt].r); else G[++cnt] = E[i]; }*/ int cost = 0; int L=1,R=1; int ans = 0; for (int i = 1; i<=N; i++) { while(R+1<=cnt&&cost+G[R+1].l-G[R].r-1<=M) { cost+=G[R+1].l-G[R].r-1; R++; } ans=max(ans,G[R].r-G[L].l+1+M-cost); cost-=G[L+1].l-G[L].r-1; L++; } /*int ans = G[1].r - G[1].l+1; int sum = ans + M; for (int i = 2; i<=cnt; i++){ ans += (G[i].r - G[i-1].r); cost += (G[i].l - G[i-1].r - 1); while (cost > M){ ans -= (G[L+1].l - G[L].l); cost -= (G[L+1].l - G[L].r - 1); L++; } sum = max(sum,ans+M-cost); } */ cout << ans <<endl; } return 0; }
路径计数 计数+NTT
#include <bits/stdc++.h> const long long MOD = 998244353; const double ex = 1e-10; typedef long long LL; #define inf 0x3f3f3f3f using namespace std; const int N = 16064; const int p = 998244353; const int G = 3; const int NUM = 25; LL x1[N],x2[N],wn[NUM]; LL F[N],Finv[N],inv[N]; inline LL quick_mod(LL a,LL b,LL m){ LL ans = 1; a %= m; while (b){ if (b % 2 == 1)ans = ans * a % m; b/=2; a = a * a % m; } return ans; } inline void GetWn(){ for (int i = 0 ; i <NUM ; i++){ int t = 1 << i; wn[i] = quick_mod(G,(p-1)/t,p); } } inline void Rader(LL a[],int len){ int j = len >> 1; for (int i = 1 ; i< len- 1; i++){ if (i <j) swap(a[i],a[j]); int k = len >> 1; while( j >= k){ j-=k;k>>=1; } if ( j < k ) j+=k; } } inline void NTT(LL a[],int len,int on){ Rader(a,len); int id = 0; for (int h = 2; h <=len ; h <<=1){ id ++; for (int j = 0 ; j< len ; j+=h){ LL w = 1; for (int k = j ; k < j + h/2 ; k++){ LL u = a[k] % p; LL t = w * ( ( a[k+h/2] ) % p ) % p; // 注意a的下标 a[k] = (u+t) %p; a[k + h / 2] = (((u-t) % p) + p) % p; w = w * wn[id] % p; } } } if (on == -1){ for (int i = 1; i<len/2 ; i++){ swap(a[i],a[len-i]); } LL Inv = quick_mod(len,p-2,p); for (int i = 0; i<len; i++){ a[i] = a[i] % p * Inv % p; } } } inline void conv(LL a[],LL b[],int n){ NTT(a,n,1); NTT(b,n,1); for (int i = 0 ; i < n; i++) a[i] = a[i] * b[i] % p; NTT(a,n,-1); } inline void init(){ inv[1] = 1; for (int i = 2; i<N; i++){ inv[i] = (MOD-MOD/i) *1ll *inv[MOD % i] % MOD; } F[0] = Finv[0] = 1; for (int i = 1 ;i<N; i++){ F[i] = F[i-1] * i % MOD; Finv[i] = Finv[i-1] *1ll*inv[i] % MOD; } return; } LL A[5][16064]; inline void getA(int d,int id){ for (int i = 1 ; i <= d ; i++){ A[id][i] = F[d-1]*Finv[i-1]%MOD * Finv[d-i] % MOD * Finv[i] % MOD; } } int main() { init(); GetWn(); int aa[5]; while (cin >> aa[1] >> aa[2] >> aa[3] >> aa[4]){ memset(A,0,sizeof(A)); int len = 0; for (int i = 1; i<=4; i++){ getA(aa[i],i); len += aa[i]; } int l = 1; while (l < 2 * (len + 1)) l<<=1; // l 为扩展长度 conv(A[1],A[2],l); conv(A[1],A[3],l); conv(A[1],A[4],l); long long ans = 0; long long f=1; for (int i = 1; i<=len ; i++){ if ((len-i) % 2 ) f = -1LL; else f = 1LL; ans = (ans + f * F[i] * A[1][i] % MOD + MOD )%MOD; } cout << (ans % MOD ) << endl; } }
复赛
Arithmetic of Bomb 模拟
#include <bits/stdc++.h> const long long mod = 1e9+7; const double ex = 1e-10; #define inf 0x3f3f3f3f using namespace std; long long yw[20000]; int main() { int T; cin >> T; yw[0] = 1; for (int i = 1;i<=9999;i++) { yw[i] = (yw[i-1]*10)%mod; } while (T--) { string s; cin >> s; long long ans = 0; for (int i = 0; i<s.length();i++){ if (s[i] == '(') { int cnt = 0; long long p = 0; while (s[i+1]!=')') { i++; cnt++; p = (p+(s[i]-'0')) % mod; if (s[i+1]!=')') p = p*10 % mod; } i++; int tmp = s[i+3]-'0'; for (int j = 1;j<=tmp;j++) ans = (ans * yw[cnt] % mod + p) % mod; i+=4; } else{ ans = (ans * 10 + (s[i] - '0')) % mod; } } cout << ans <<endl; } return 0; }
Pokémon GO 找规律
#include <bits/stdc++.h> const long long mod = 1e9+7; const double ex = 1e-10; #define inf 0x3f3f3f3f using namespace std; long long F[10008]; long long po[10008]; int main() { int T; cin >> T; F[1] = 2; F[2] = 12; po[0] = 1; for (int i = 1; i<=10000;i++) po[i] = (po[i-1]*2LL)% mod; for (int i = 3;i<=10000 ;i++) F[i] = ((((F[i-1]*2LL) % mod)+ (4LL * F[i-2]) % mod) % mod + po[i]) % mod; for (int i = 1; i<=T;i++) { long long n; cin >> n; if (n==1) {cout << 2 << endl;continue;} long long ans = (F[n] * 2LL) % mod; for (int i = 2; i<n;i++) ans = (ans + ((po[i]*F[n-i]) % mod + (po[n-i+1]*F[i-1]) % mod) % mod) % mod; cout << ans <<endl; } return 0; }
Valley Numer 数位DP
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> using namespace std; const long long mod = 1000000007; typedef long long LL; char s[105]; int tot[150]; int T, len; LL f[3][105][100]; LL dfs(int fuckp, int pre, int flag, int fuckl, int fuckz) { if(fuckp <= 0) { if(!fuckz) return 1; else return 0; } if(!fuckl && !fuckz && f[flag][fuckp][pre] != -1) return f[flag][fuckp][pre]; int ed = (fuckl ? tot[fuckp] : 9); LL res = 0; for(int i = 0; i <= ed; i++) { if(flag == 1) { if(pre > i) continue; else res = (res + dfs(fuckp - 1, i, 1, fuckl && (i == ed), 0)) % mod; } else { if(fuckz) { if(i == 0) res = (res + dfs(fuckp - 1, i, 0, fuckl && (i == ed), 1)) % mod; else res = (res + dfs(fuckp - 1, i, 0, fuckl && (i == ed), 0)) % mod; } else { if(i > pre) res = (res + dfs(fuckp - 1, i, 1, fuckl && (i == ed), 0)) % mod; else res = (res + dfs(fuckp - 1, i, 0, fuckl && (i == ed), 0)) % mod; } } } if(!fuckz && !fuckl) return f[flag][fuckp][pre] = res % mod; return res % mod; } int main() { for (scanf("%d", &T); T; T --) { memset(tot, 0, sizeof(tot)); memset(f, -1, sizeof f); scanf ("%s", s); len = strlen(s); int cnt = 0; for (int i = len - 1; i >= 0; i--) tot[++cnt] = s[i] - '0'; cout << (dfs(cnt, 0, 0, 1, 1) % mod) << endl; } return 0; }
Valley Numer II 状压DP
#include <bits/stdc++.h> const long long mod = 1e9+7; const double ex = 1e-10; #define inf 0x3f3f3f3f using namespace std; vector <int> E[40]; vector <int> EB[40]; vector <int> w; int id[40]; int hh[40]; int dp[40][70000]; int main() { int T; cin >> T; while (T--){ int N,M,K; cin >> N >> M >>K; memset(hh,0,sizeof(hh)); memset(dp,-1,sizeof(dp)); w.clear(); for (int i = 1; i<=N;i++) E[i].clear(),EB[i].clear(); for (int i = 1 ; i<=M; i++){ int a,b; cin >> a >> b; E[a].push_back(b); E[b].push_back(a); } for (int i = 1; i<=K;i++){ int a;cin >> a; hh[a]=1; } int cnt = 0; for (int i = 1; i <= N; i++){ if (hh[i]) id[i] = cnt++; else w.push_back(i); } int sizew = w.size(); for (int i = 1;i<=N ;i++){ if (hh[i]) continue; for (int j = 0; j<E[i].size(); j++) if (hh[E[i][j]]) EB[i].push_back(E[i][j]); } // DP dp[0][0] = 0; int v1,v2; int top = 1<<(cnt); for (int i = 1; i<=sizew ;i++){ int u = w[i-1]; for (int s = 0 ; s < top ; s++){ dp[i][s] = max(dp[i-1][s],dp[i][s]); if (dp[i-1][s] == -1) continue; for (int j = 0;j<EB[u].size(); j++){ v1 = EB[u][j]; if (( s & (1<<id[v1]) ) != 0) continue; for (int k = j+1; k<EB[u].size() ; k++){ v2 = EB[u][k]; if (( s & (1<<id[v2]) ) != 0) continue; dp[i][s | (1<<id[v1]) | (1<<id[v2])] = max(dp[i-1][s] + 1,dp[i][s | (1<<id[v1]) | (1<<id[v2])]); } } } } int ans = 0; for (int s=0;s<top;s++){ ans = max(dp[sizew][s],ans); } cout << ans <<endl; } return 0; }