noip2014解题报告
D2T3:
秦九韶算法
#include<cstdio> #include<cstring> #include<iostream> #include<cstdlib> #include<algorithm> #define ll long long using namespace std; const int maxn=1e2+5; const int maxm=1e7+5; const ll P1=999653; const ll P2=673313; const ll P3=999983; ll a[maxn][5],ans[maxm]; int n,m; inline void read(int i){ a[i][1]=a[i][2]=a[i][3]=0ll; ll b=1; char x=getchar(); while(x<'0'||'9'<x){ if(x=='-')b=-1; x=getchar(); } while('0'<=x&&x<='9'){ a[i][1]=( (a[i][1]<<1) + (a[i][1]<<3) + x-'0')%P1; a[i][2]=( (a[i][2]<<1) + (a[i][2]<<3) + x-'0')%P2; a[i][3]=( (a[i][3]<<1) + (a[i][3]<<3) + x-'0')%P3; x=getchar(); } a[i][1]*=b; a[i][2]*=b; a[i][3]*=b; } inline int read2(){ int a=0;bool b=1;char x=getchar(); while(x<'0'||'9'<x){ if(x=='-')b=0; x=getchar(); } while('0'<=x&&x<='9'){ a=(a<<1)+(a<<3)+x-'0'; x=getchar(); } return b ? a : -a ; } int main() { //freopen("equation.in","r",stdin); //freopen("equation.out","w",stdout); n=read2();m=read2(); for(int i=0;i<=n;i++){ read(i); } for(int i=1;i<=m;i++){ ll k1=0,k2=0,k3=0; for(int j=n;j>=0;j--){ k1=(k1*i+a[j][1])%P1; k2=(k2*i+a[j][2])%P2; k3=(k3*i+a[j][3])%P3; } if( (!k1) && (!k2) && (!k3) )ans[ ++ans[0] ]=i; } for(int i=0;i<=ans[0];i++){ printf("%lld\n",ans[i]); } return 0; } /*10457is prime 10459is prime 10463is prime*/
D1T2:
树dp O(n):
#include<cstdio> #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cmath> using namespace std; const int P=10007; const int maxn=2e5+5; inline int read(){ int a=0;bool b=1;char x=getchar(); while(x<'0'||'9'<x){ if(x=='-')b=0; x=getchar(); } while('0'<=x&&x<='9'){ a=(a<<1)+(a<<3)+x-'0'; x=getchar(); } return b ? a : -a ; } int first[maxn],next[maxn*2],to[maxn*2],edge_count; inline void add(int x,int y){ edge_count++; to[edge_count]=y; next[edge_count]=first[x]; first[x]=edge_count; } int n,w[maxn],ans,sonmax[maxn],soncnt[maxn],f[maxn]; void search(int root ,int fa){ sonmax[root]=f[root]=soncnt[root]=0; for(int i=first[root];i;i=next[i]){ int v=to[i]; if(v==fa)continue; search(v,root); f[root]=(f[root]+ w[root]*soncnt[v] + w[v]*soncnt[root]) % P; ans=max(ans,max ( w[root]*sonmax[v] , w[v]*sonmax[root] ) ); soncnt[root]=(soncnt[root]+w[v])%P; sonmax[root]=max(sonmax[root],w[v]); } } int main() { //freopen("link.in","r",stdin); //freopen("link.out","w",stdout); n=read(); for(int i=1,u,v;i<n;i++){ u=read();v=read(); add(u,v);add(v,u); } for(int i=1;i<=n;i++){ w[i]=read(); } search(1,0); printf("%d ",ans); ans=0; for(int i=1;i<=n;i++){ ans=(ans+f[i])%P; } printf("%d",(ans*2)%P); return 0; }
或者
暴力 O(n):
#include<cstdio> #include<algorithm> #include<iostream> #include<cstring> #include<cstdlib> #include<cmath> using namespace std; const int P=10007; const int maxn=2e5+5; inline int read(){ int a=0;bool b=1;char x=getchar(); while(x<'0'||'9'<x){ if(x=='-')b=0; x=getchar(); } while('0'<=x&&x<='9'){ a=(a<<1)+(a<<3)+x-'0'; x=getchar(); } return b ? a : -a ; } int n,w[maxn],ans[2]; int first[maxn],next[maxn*2],to[maxn*2],edge_count; inline void add(int x,int y){ edge_count++; to[edge_count]=y; next[edge_count]=first[x]; first[x]=edge_count; } inline void solve(int u){ int Max=0,sum=0; for(int i=first[u];i;i=next[i]){ int v=to[i]; ans[1]=(ans[1]+w[v]*sum)%P; ans[0]=max(ans[0],w[v]*Max); Max=max(Max,w[v]); sum=(sum+w[v])%P; } } int main() { n=read(); for(int i=1,u,v;i<n;i++){ u=read();v=read(); add(u,v);add(v,u); } for(int i=1;i<=n;i++){ w[i]=read(); } for(int i=1;i<=n;i++){ solve(i); } printf("%d %d",ans[0],(ans[1]*2)%P); return 0; }
D1T1:sb题
#include<cstdio> #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cmath> using namespace std; const int maxn=2e2+5; inline int read(){ int a=0;bool b=1;char x=getchar(); while(x<'0'||'9'<x){ if(x=='-')b=0; x=getchar(); } while('0'<=x&&x<='9'){ a=(a<<1)+(a<<3)+x-'0'; x=getchar(); } return b ? a : -a ; } int score[10][10]={ {0,0,1,1,0}, {1,0,0,1,0}, {0,1,0,0,1}, {0,0,1,0,1}, {1,1,0,0,0}, }; int n,na,nb,a[maxn],b[maxn],ansa,ansb; int main() { //freopen("rps.in","r",stdin); //freopen("rps.out","w",stdout); n=read();na=read();nb=read(); for(int i=1;i<=na;i++)a[i]=read(); for(int i=1;i<=nb;i++)b[i]=read(); int pa=1,pb=1; for(int i=1;i<=n;i++){ ansa+=score[ a[pa] ][ b[pb] ]; ansb+=score[ b[pb] ][ a[pa] ]; pa++;pb++; if(pa==na+1)pa=1; if(pb==nb+1)pb=1; } printf("%d %d",ansa,ansb); return 0; }
D1T3:
huge DP:
wa:
#include<cstdio> #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cmath> using namespace std; const int maxn=1e4+5; const int maxm=1e3+5; const int N=0x3f3f3f3f; inline int read(){ int a=0;bool b=1;char x=getchar(); while(x<'0'||'9'<x){ if(x=='-')b=0; x=getchar(); } while('0'<=x&&x<='9'){ a=(a<<1)+(a<<3)+x-'0'; x=getchar(); } return b ? a : -a ; } int n,m,k,up[maxn],down[maxn],f[maxn][maxm][2],p[maxn][2],ans1,ans2; int now[maxm]; bool vis[maxn]; int main() { // freopen("bird.in","r",stdin); //freopen("bird.out","w",stdout); memset(f,0x3f,sizeof(f)); n=read();m=read();k=read(); for(int i=1;i<=n;i++){ up[i]=read();down[i]=read(); } for(int i=0;i<=n;i++){ p[i][0]=1;p[i][1]=m; } for(int i=1,P,L,H;i<=k;i++){ P=read();L=read();H=read(); p[P][0]=L+1;p[P][1]=H-1; vis[P]=1; } ans2=N; ans1=vis[0]; for(int i=p[0][0];i<=p[0][1];i++){ f[0][i][0]=f[0][i][1]=0; } for(int i=1;i<=n;i++){ bool flag=0; for(int j=0;j<=m;j++){ now[j]=N; } for(int j=1;j<=m;j++){ if(p[i][0]<=j&&j<=p[i][1]){ if(j+down[i]<=m) f[i][j][0]=min(f[i-1][ j+down[i] ][0] , f[i-1][ j+down[i] ][1]); if(j>up[i]) f[i][j][1]=min( min( f[i-1][ j-up[i] ][0] , f[i-1][ j-up[i] ][1] ) , now[ j-up[i] ])+1; if(j==m){ for(int k=max(p[i-1][0],m-up[i]+1);k<=p[i-1][1];k++){ f[i][m][1]=min(f[i][m][1],min( now[k]+1 , min(f[i-1][k][0]+1 , f[i-1][k][1]+1 ) ) ); } } int t=min(f[i][j][0],f[i][j][1]); if(t<N)flag=1; if(i==n)ans2=min(ans2,t); } if(j>up[i])now[j]=min( min( f[i-1][ j-up[i] ][0] , f[i-1][ j-up[i] ][1] ) , now[ j-up[i] ] )+1; } if(!flag){ printf("0\n"); printf("%d",ans1); return 0; } else ans1+=vis[i]; } printf("1\n"); printf("%d",ans2); return 0; }
ac:
傻逼错因分析:
因为 本题的特殊要求,可以一直点击上升
所以每次的dp中 j==m时必须特判
但是有个问题,就是特判时状态从谁而来?
显然是 i-1 列的最大起始位置,也就是障碍物底端 和 m-up[i-1] 的 最大值
但是考虑到可以无限上升,所以此次转移的上届!!!必须到m!!!,否则就傻逼
#include<cstdio> #include<algorithm> #include<iostream> #include<cstdlib> #include<cstring> #include<cmath> using namespace std; const int maxn=1e4+5; const int maxm=1e3+5; const int N=0x3f3f3f3f; inline int read(){ int a=0;bool b=1;char x=getchar(); while(x<'0'||'9'<x){ if(x=='-')b=0; x=getchar(); } while('0'<=x&&x<='9'){ a=(a<<1)+(a<<3)+x-'0'; x=getchar(); } return b ? a : -a ; } int n,m,k,up[maxn],down[maxn],f[maxn][maxm][2],p[maxn][2],ans1,ans2; int now[maxm]; bool vis[maxn]; int main() { //freopen("bird.in","r",stdin); //freopen("bird.out","w",stdout); memset(f,0x3f,sizeof(f)); n=read();m=read();k=read(); for(int i=1;i<=n;i++){ up[i]=read();down[i]=read(); } for(int i=0;i<=n;i++){ p[i][0]=1;p[i][1]=m; } for(int i=1,P,L,H;i<=k;i++){ P=read();L=read();H=read(); p[P][0]=L+1;p[P][1]=H-1; vis[P]=1; } /*for(int i=1;i<=50;i++){ printf("%d ",up[i]); } putchar('\n'); for(int i=1;i<=50;i++){ printf("%d ",down[i]); } putchar('\n');*/调试过程忽略 ans2=N; ans1=vis[0]; for(int i=p[0][0];i<=p[0][1];i++){ f[0][i][0]=f[0][i][1]=0; } for(int i=1;i<=n;i++){ bool flag=0; for(int j=0;j<=m;j++){ now[j]=N; } for(int j=1;j<=m;j++){ if(p[i][0]<=j&&j<=p[i][1]){ if(j+down[i]<=m) f[i][j][0]=min(f[i-1][ j+down[i] ][0] , f[i-1][ j+down[i] ][1]); if(j>up[i]) f[i][j][1]=min( min( f[i-1][ j-up[i] ][0] , f[i-1][ j-up[i] ][1] ) , now[ j-up[i] ])+1; if(j==m){//特判:注意k的终止边界 从k<=p[i-1][1] 变成 k<=m for(int k=max(p[i-1][0],m-up[i]+1);k<=m;k++){ f[i][m][1]=min(f[i][m][1],min( now[k]+1 , min(f[i-1][k][0]+1 , f[i-1][k][1]+1 ) ) ); } } int t=min(f[i][j][0],f[i][j][1]); if(t<N)flag=1;//printf("%d %d\n",i,j); if(i==n)ans2=min(ans2,t); } if(j>up[i])now[j]=min( min( f[i-1][ j-up[i] ][0] , f[i-1][ j-up[i] ][1] ) , now[ j-up[i] ] )+1; } if(!flag){ printf("0\n"); printf("%d",ans1); return 0; } else ans1+=vis[i]; } printf("1\n"); printf("%d",ans2); return 0; }
D2T2:
wa:
#include<cstdio> #include<cstring> #include<iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<functional> using namespace std; const int maxn=1e4+5; const int maxm=2e5+5; const int N=0x3f3f3f3f; inline int read(){ int a=0;bool b=1;char x=getchar(); while(x<'0'||'9'<x){ if(x=='-')b=0; x=getchar(); } while('0'<=x&&x<='9'){ a=(a<<1)+(a<<3)+x-'0'; x=getchar(); } return b ? a : -a ; } int first[maxn][2],next[maxm][2],to[maxm][2],edge_count[2]; inline void add(int x,int y,int b){ edge_count[b]++; to[edge_count[b]][b]=y; next[edge_count[b]][b]=first[x][b]; first[x][b]=edge_count[b]; } int dfn[maxn],S[maxn],low[maxn],Time,p,scc[maxn],temp; void tarjan(int u){ dfn[u]=low[u]=++Time; S[++p]=u; for(int i=first[u][0];i;i=next[i][0]){ int v=to[i][0]; if(!dfn[v]){ tarjan(v); low[u]=min(low[u],low[v]); } else if(!scc[v])low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]){ temp++; while(S[p+1]!=u){ scc[ S[p] ]=temp; p--; } } } int n,m,s,t; bool acp[maxn],vis[maxn];//acp[i]璇ョ偣鏄惁鑳藉埌杈剧粓鐐?vis[i]!!!璇ュ己鑱旈€氬垎閲?!!鏄惁琚玝fs鍒? inline void bfs(int x){ int front=0,rear=0; S[rear++]=x; vis[x]=1; while(front<rear){ int u=S[front]; for(int i=first[u][1];i;i=next[i][1]){ int v=to[i][1]; if(!vis[v]){ vis[v]=1; S[rear++]=v; } } front++; } } inline void solve(int u){ acp[u]=1; for(int i=first[u][0];i;i=next[i][0]){ int v=to[i][0]; if(!vis[ scc[v] ]){acp[u]=0;break;} } } int dis[maxn]; priority_queue<pair<int,int> ,vector<pair<int,int> > ,less<pair<int,int> > >q; //acp[i]璇ョ偣鏄惁鑳藉埌杈剧粓鐐?vis[i]璇ョ偣鏄惁姹傚嚭鏈€鐭矾 inline void dijkstra(int s,int t){ memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[s]=0; q.push(make_pair(0,s)); while(q.size()){ int pos=q.top().second; q.pop(); if(vis[pos])continue; vis[pos]=1; for(int i=first[pos][0];i;i=next[i][0]){ int v=to[i][0]; if(vis[v] || !acp[v])continue; int k=dis[pos]+1; if(k<dis[v]){dis[v]=k;q.push(make_pair(dis[v],v));} } } } bool link[maxn][maxn]; int main() { //freopen("road.in","r",stdin); //freopen("road.out","w",stdout); n=read();m=read(); for(int i=1,u,v;i<=m;i++){ u=read();v=read(); if(!link[u][v] && u!=v)add(u,v,0);//鍒ら噸杈癸紵锛熸湁鐢紵 link[u][v]=1; } s=read();t=read(); for(int i=1;i<=n;i++){ if(!dfn[i])tarjan(i); } for(int i=1;i<=n;i++){ for(int j=first[i][0];j;j=next[j][0]){ if(scc[i]==scc[ to[j][0] ])continue; add(scc[ to[j][0] ],scc[i],1);//鍙嶅悜寤鸿竟bfs锛堬級 } } bfs(scc[ t ]); for(int i=1;i<=n;i++){ if(vis[ scc[i] ])solve(i); } dijkstra(s,t); printf("%d ",dis[t]==N?-1:dis[t]); //for(int i=1;i<=n;i++){printf("%d ",dis[i]);} return 0; }
ac?:
D2T2:
wa:
#include<cstdio> #include<cstring> #include<iostream> #include<cstdlib> #include<algorithm> #include<cmath> #include<queue> #include<functional> using namespace std; const int maxn=1e4+5; const int maxm=2e5+5; const int N=0x3f3f3f3f; inline int read(){ int a=0;bool b=1;char x=getchar(); while(x<'0'||'9'<x){ if(x=='-')b=0; x=getchar(); } while('0'<=x&&x<='9'){ a=(a<<1)+(a<<3)+x-'0'; x=getchar(); } return b ? a : -a ; } int first[maxn][2],next[maxm][2],to[maxm][2],edge_count[2]; inline void add(int x,int y,int b){ edge_count[b]++; to[edge_count[b]][b]=y; next[edge_count[b]][b]=first[x][b]; first[x][b]=edge_count[b]; } int dfn[maxn],S[maxn],low[maxn],Time,p,scc[maxn],temp; void tarjan(int u){ dfn[u]=low[u]=++Time; S[++p]=u; for(int i=first[u][0];i;i=next[i][0]){ int v=to[i][0]; if(!dfn[v]){ tarjan(v); low[u]=min(low[u],low[v]); } else if(!scc[v])low[u]=min(low[u],dfn[v]); } if(dfn[u]==low[u]){ temp++; while(S[p+1]!=u){ scc[ S[p] ]=temp; p--; } } } int n,m,s,t; bool acp[maxn],vis[maxn];//acp[i]璇ョ偣鏄惁鑳藉埌杈剧粓鐐?vis[i]!!!璇ュ己鑱旈€氬垎閲?!!鏄惁琚玝fs鍒? inline void bfs(int x){ int front=0,rear=0; S[rear++]=x; vis[x]=1; while(front<rear){ int u=S[front]; for(int i=first[u][1];i;i=next[i][1]){ int v=to[i][1]; if(!vis[v]){ vis[v]=1; S[rear++]=v; } } front++; } } inline void solve(int u){ acp[u]=1; for(int i=first[u][0];i;i=next[i][0]){ int v=to[i][0]; if(!vis[ scc[v] ]){acp[u]=0;break;} } } int dis[maxn]; priority_queue<pair<int,int> ,vector<pair<int,int> > ,less<pair<int,int> > >q; //acp[i]璇ョ偣鏄惁鑳藉埌杈剧粓鐐?vis[i]璇ョ偣鏄惁姹傚嚭鏈€鐭矾 inline void dijkstra(int s,int t){ memset(dis,0x3f,sizeof(dis)); memset(vis,0,sizeof(vis)); dis[s]=0; q.push(make_pair(0,s)); while(q.size()){ int pos=q.top().second; q.pop(); if(vis[pos])continue; vis[pos]=1; for(int i=first[pos][0];i;i=next[i][0]){ int v=to[i][0]; if(vis[v] || !acp[v])continue; int k=dis[pos]+1; if(k<dis[v]){dis[v]=k;q.push(make_pair(dis[v],v));} } } } bool link[maxn][maxn]; int main() { //freopen("road.in","r",stdin); //freopen("road.out","w",stdout); n=read();m=read(); for(int i=1,u,v;i<=m;i++){ u=read();v=read(); if(!link[u][v] && u!=v)add(u,v,0);//鍒ら噸杈癸紵锛熸湁鐢紵 link[u][v]=1; } s=read();t=read(); for(int i=1;i<=n;i++){ if(!dfn[i])tarjan(i); } for(int i=1;i<=n;i++){ for(int j=first[i][0];j;j=next[j][0]){ if(scc[i]==scc[ to[j][0] ])continue; add(scc[ to[j][0] ],scc[i],1);//鍙嶅悜寤鸿竟bfs锛堬級 } } bfs(scc[ t ]); for(int i=1;i<=n;i++){ if(vis[ scc[i] ])solve(i); } dijkstra(s,t); printf("%d ",dis[t]==N?-1:dis[t]); //for(int i=1;i<=n;i++){printf("%d ",dis[i]);} return 0; }