2016ccpc 网络选拔赛题解
A 模拟大数取模
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn = 10000000 + 1; const int mod = 10001; char s[maxn]; int main(){ int kase = 0; while(scanf("%s",s) == 1){ int len = strlen(s); int v = 0; for (int i = 0; i < len; ++i){ v = (v*10 + s[i]-48) % mod; } if (v == 0)printf("Case #%d: YES\n",++kase); else printf("Case #%d: NO\n",++kase); } return 0; }
B 高斯消元(zwz口胡会写,未实现)
C 换根dp维护
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll,ll> pll; const int N=5e5+10; const int inf=0x3f3f3f3f; const ll mod=998244353; int a[N],n; int h[N],ne[N],e[N],w[N],idx; int f[N][2],g[N][2]; int id[N]; void add(int a,int b,int c){ e[idx]=b,ne[idx]=h[a],w[idx]=c,h[a]=idx++; } void dfs(int u,int fa){ f[u][0]=f[u][1]=a[u]; int i; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==fa) continue; dfs(j,u); f[u][1]+=max(0,f[j][0]-2*w[i]); if(f[u][0]+f[j][1]-w[i]>f[u][1]){ f[u][1]=f[u][0]+f[j][1]-w[i]; id[u]=j; } f[u][0]+=max(0,f[j][0]-2*w[i]); } } void get(int u,int fa){ if(f[u][0]+g[u][1]>f[u][1]+g[u][0]){ id[u]=fa; } int i; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==fa) continue; if(j==id[u]){ int tmp1=g[u][1]+a[u],tmp2=g[u][0]+a[u];//tmp1目前是父亲往上的停留点,tmp2目前是回到父亲的点 for(int k=h[u];k!=-1;k=ne[k]){ int v=e[k]; if(v==j||v==fa) continue; tmp1+=max(0,f[v][0]-2*w[k]); if(tmp2+max(f[v][1]-w[k],0)>tmp1){ tmp1=tmp2+max(0,f[v][1]-w[k]); } tmp2+=max(0,f[v][0]-2*w[k]); } g[j][0]=max(0,tmp2-2*w[i]);//回到当前点的最大值 g[j][1]=max(0,tmp1-w[i]);//停留在上面的最大值 } else{ int tmp; if(f[j][0]>=2*w[i]){ tmp=f[j][0]-2*w[i]; } else{ tmp=0; } g[j][0]=max(0,f[u][0]+g[u][0]-tmp-2*w[i]); g[j][1]=max(0,max(g[u][1]+f[u][0]-tmp-w[i],f[u][1]+g[u][0]-tmp-w[i])); } get(j,u); } } int main(){ ios::sync_with_stdio(false); int t; cin>>t; int cnt=1; while(t--){ cin>>n; int i; idx=0; for(i=0;i<=n;i++){ h[i]=-1; f[i][1]=f[i][0]=g[i][1]=g[i][0]=0; id[i]=-1; } for(i=1;i<=n;i++) cin>>a[i]; for(i=1;i<n;i++){ int a,b,c; cin>>a>>b>>c; add(a,b,c); add(b,a,c); } dfs(1,-1); get(1,-1); cout<<"Case #"<<cnt++<<":"<<endl; for(i=1;i<=n;i++){ cout<<(max(f[i][0]+g[i][1],f[i][1]+g[i][0]))<<endl; } } return 0; }
D 贪心乱搞,我的做法是排序后枚举贪心查看情况
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll,ll> pll; const int N=5e5+10; const int inf=0x3f3f3f3f; const ll mod=998244353; int a[N]; int main(){ ios::sync_with_stdio(false); int t; cin>>t; int idx=1; while(t--){ int n; cin>>n; int i; int sum=0; for(i=1;i<=n;i++){ cin>>a[i]; sum+=a[i]; } sort(a+1,a+1+n); int tmp=0; int cnt=0; for(i=1;i<=n;i++){ if(i==n){ if(sum-tmp-1>=tmp+1){ cnt++; break; } } if(cnt+(2*a[i])<=sum-tmp-2*a[i]){ a[i+1]-=a[i]; cnt+=2*a[i]; tmp+=2*a[i]; } else{ int j; for(j=1;j<=a[i];j++){ if(cnt+2*j>sum-tmp-2*j){ if(cnt+2*j-1<=sum-tmp-2*j+1){ cnt+=2*j-1; break; } else{ cnt+=2*(j-1); break; } } } break; } } cout<<"Case #"<<idx++<<": "; cout<<cnt<<endl; } return 0; }
G 状压dp+容斥原理
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll,ll> pll; const int N=5e5+10; const int inf=0x3f3f3f3f; const int mod=772002; int n,m; int f[30][1200]; char g[30][30]; char tmp[30][30]; map<int,pll> m1; int pos[N],mou[N]; ll ans; int dx[]={-1,-1,0,1,1,1,0,-1}; int dy[]={0,1,1,1,0,-1,-1,-1}; int sx[N],sy[N]; bool check(){ int i,j; for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ if(g[i][j]!='X') continue; for(int k=0;k<8;k++){ int x=i+dx[k]; int y=j+dy[k]; if(x&&x<=n&&y&&y<=m){ if(g[x][y]=='X') return true; } } } } return false; } ll solve(){ int i,j; memset(f,0,sizeof f); f[0][0]=1; int cnt=0; int num=n*m; for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ if(g[i][j]=='X'){ cnt++; sx[cnt-1]=i; sy[cnt-1]=j; } } } memset(tmp,'.',sizeof tmp); int mx=1<<cnt; for(i=0;i<mx;i++){ mou[i]=0; for(j=0;j<cnt;j++){ if(i>>j&1){ mou[i]++; } else{ tmp[sx[j]][sy[j]]='Y'; } } pos[i]=num-cnt; for(int l=1;l<=n;l++){ for(int r=1;r<=m;r++){ if(g[l][r]=='X') continue; for(int k=0;k<8;k++){ int a=l+dx[k]; int b=r+dy[k]; if(a<=n&&a&&b&&b<=m){ if(tmp[a][b]=='Y'){ pos[i]--; break; } } } } } for(int k=0;k<cnt;k++){ tmp[sx[k]][sy[k]]='.'; } } for(i=0;i<num;i++){ for(j=0;j<mx;j++){ if(!f[i][j]) continue; for(int k=0;k<cnt;k++){ if(!((j>>k)&1)){ f[i+1][j|(1<<k)]=(f[i+1][j|(1<<k)]+f[i][j])%mod; } } f[i+1][j]=(f[i+1][j]+f[i][j]*(pos[j]-i+mou[j])%mod)%mod; } } return f[num][mx-1]; } void dfs(int u,int num){ if(u==n*m+1){ if(num%2==0) ans=(ans+solve())%mod; else ans=(ans-solve()+mod)%mod; return ; } int x=m1[u].first; int y=m1[u].second; int i; for(i=0;i<8;i++){ int a=x+dx[i]; int b=y+dy[i]; if(a&&a<=n&&b&&b<=m){ if(g[a][b]=='X') break; } } if(i==8&&g[x][y]=='.'){ g[x][y]='X'; dfs(u+1,num+1); g[x][y]='.'; } dfs(u+1,num); } int main(){ ios::sync_with_stdio(false); int times=1; while(cin>>n>>m){ m1.clear(); int i,j; int id=0; for(i=1;i<=n;i++){ for(j=1;j<=m;j++){ cin>>g[i][j]; m1[++id]={i,j}; } } if(check()){ cout<<"Case #"<<times++<<": "; cout<<0<<endl; } else{ ans=0; dfs(1,0); cout<<"Case #"<<times++<<": "; cout<<ans<<endl; } } return 0; }
J Trie+启发式合并
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll,ll> pll; const int N=2e5+10; const int M=2e6+10; const int inf=0x3f3f3f3f; const int mod=772002; int h[N],ne[N],e[N],idx; int n,tr[M][2],rt[N]; int w[N],times; int ans[N]; int p[M],val[M]; int sum[M]; void add(int a,int b){ e[idx]=b,ne[idx]=h[a],h[a]=idx++; } int query(int u,int k,int dep){ if(dep==-1) return val[u]; int sign=(k>>dep)&1; if(tr[u][sign]) return query(tr[u][sign],k,dep-1); else return query(tr[u][sign^1],k,dep-1); } void pushup(int u,int dep){ int l=tr[u][0],r=tr[u][1]; sum[u]=sum[l]+sum[r]; if(sum[l]==1&&sum[r]==1){ p[u]=p[l]^p[r]; } else if(!sum[l]||!sum[r]){ p[u]=sum[l]?p[l]:p[r]; } else if(sum[l]>1&&sum[r]>1){ p[u]=max(p[l],p[r]); } else{ if(sum[l]!=1) swap(l,r); p[u]=p[l]^query(r,p[l],dep-1); } } void insert(int &u,int dep,int k){ int i; if(!u) u=++times; if(dep==-1){ sum[u]=1; p[u]=val[u]=k; return ; } if(k>>dep&1) insert(tr[u][1],dep-1,k); else insert(tr[u][0],dep-1,k); pushup(u,dep); } int Merge(int u,int v,int dep){ int i; if(!u||!v) return u|v; if(dep==-1){ sum[u]+=sum[v]; if(sum[u]>1){ p[u]=0; } else{ p[u]=val[u]; } return u; } tr[u][0]=Merge(tr[u][0],tr[v][0],dep-1); tr[u][1]=Merge(tr[u][1],tr[v][1],dep-1); pushup(u,dep); return u; } void dfs(int u,int fa){ insert(rt[u],16,w[u]); int i; for(i=h[u];i!=-1;i=ne[i]){ int j=e[i]; if(j==fa) continue; dfs(j,u); rt[u]=Merge(rt[u],rt[j],16); } if(sum[rt[u]]>1) ans[u]=p[rt[u]]; } void init(){ int i; times=0,idx=0; memset(h,-1,sizeof h); memset(sum,0,sizeof sum); memset(ans,-1,sizeof ans); memset(rt,0,sizeof rt); memset(tr,0,sizeof tr); } int main(){ ios::sync_with_stdio(false); int t; cin>>t; int cnt=1; while(t--){ cin>>n; int i; init(); for(i=1;i<=n;i++){ cin>>w[i]; } for(i=1;i<n;i++){ int a,b; cin>>a>>b; add(a,b); add(b,a); } dfs(1,-1); int m; cin>>m; cout<<"Case #"<<cnt++<<":"<<endl; while(m--){ int u; cin>>u; cout<<ans[u]<<endl; } } return 0; }
K 水题map去重
#include<bits/stdc++.h> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<ll,ll> pll; const int N=5e5+10; const int inf=0x3f3f3f3f; const ll mod=998244353; map<char,int> m1; int main(){ ios::sync_with_stdio(false); int t; cin>>t; int cnt=1; while(t--){ string s; cin>>s; int i; m1.clear(); for(i=0;i<s.size();i++){ m1[s[i]]++; } cout<<"Case #"<<cnt++<<": "; cout<<(int)m1.size()<<endl; } return 0; }
没有人不辛苦,只有人不喊疼