Atcoder Beginner Contest 160 做题记录
Posted uuzlove
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Atcoder Beginner Contest 160 做题记录相关的知识,希望对你有一定的参考价值。
A.
水题
1 #include<bits/stdc++.h> 2 using namespace std; 3 char s[10]; 4 int main() 5 { 6 scanf("%s",s+1); 7 if(s[3]==s[4]&&s[5]==s[6])puts("Yes"); 8 else puts("No"); 9 }
B.
水题
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main() 4 { 5 int x; 6 scanf("%d",&x); 7 int A=x/500,B=x%500; 8 int C=B/5; 9 printf("%d ",1000*A+C*5); 10 }
C.
水题
1 #include<bits/stdc++.h> 2 using namespace std; 3 int k,n; 4 int a[1000005]; 5 int main() 6 { 7 scanf("%d%d",&k,&n); 8 for(int i=1;i<=n;++i)scanf("%d",&a[i]),a[i+n]=a[i]+k; 9 int ans=1000000000; 10 for(int i=1;i<=n;++i)ans=min(ans,a[i+n-1]-a[i]); 11 printf("%d ",ans); 12 }
D.
水题
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,x,y; 4 vector<int> g[2005]; 5 int Ans[2005]; 6 int dis[2005]; 7 int main() 8 { 9 scanf("%d%d%d",&n,&x,&y); 10 for(int i=1;i<n;++i)g[i].push_back(i+1),g[i+1].push_back(i); 11 g[x].push_back(y);g[y].push_back(x); 12 for(int i=1;i<=n;++i) 13 { 14 memset(dis,0,sizeof(dis)); 15 queue<int> q; 16 q.push(i);dis[i]=1; 17 while(!q.empty()) 18 { 19 int u=q.front();q.pop(); 20 for(int v:g[u])if(!dis[v])dis[v]=dis[u]+1,q.push(v); 21 } 22 for(int i=1;i<=n;++i)Ans[dis[i]-1]++; 23 } 24 for(int i=1;i<n;++i)printf("%d ",Ans[i]/2); 25 }
E.
水题
1 #include<bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 int X,Y,A,B,C; 5 struct Node 6 { 7 int val,bel; 8 }a[1000005]; 9 bool operator < (Node A,Node B) 10 { 11 if(A.val==B.val)return A.bel<B.bel; 12 return A.val<B.val; 13 } 14 int main() 15 { 16 scanf("%d%d%d%d%d",&X,&Y,&A,&B,&C); 17 int n=A+B+C,m=X+Y; 18 ll ans=0; 19 for(int i=1;i<=A;++i) 20 { 21 scanf("%d",&a[i].val); 22 a[i].bel=1; 23 } 24 for(int i=A+1;i<=A+B;++i) 25 { 26 scanf("%d",&a[i].val); 27 a[i].bel=2; 28 } 29 for(int i=A+B+1;i<=A+B+C;++i) 30 { 31 scanf("%d",&a[i].val); 32 a[i].bel=3; 33 } 34 sort(a+1,a+n+1); 35 reverse(a+1,a+n+1); 36 for(int i=1;i<=n;++i) 37 { 38 if(a[i].bel==1) 39 { 40 if(X)X--,m--,ans+=a[i].val; 41 else continue; 42 } 43 else if(a[i].bel==2) 44 { 45 if(Y)Y--,m--,ans+=a[i].val; 46 else continue; 47 } 48 else 49 { 50 m--;ans+=a[i].val; 51 } 52 if(!m)break; 53 } 54 printf("%lld ",ans); 55 }
F.
考虑以(1)为出发点怎么计数:我们可以通过一次树形DP来计数
(dp[u])表示(u)的子树中的方案数
我们枚举子树(v),考虑将(v)插入到之前遍历过的子树点集(S)中(初始为空),(S)中的方案数为暂时的(dp[u])(初始为(1))
那么显然有(dp[u]=dp[u]*dp[v]*inom{size[S]+size[v]}{size[v]})
这个式子的含义是枚举(u,v)内部合法的方案,然后把(u,v)当成两个整体有序合并,即将一个(size[v])的东西放到(size[S]+size[v])个槽里
然后这样就能算出(1)的答案了
然后考虑怎么算出(k=1,2,…,n)的答案
做一次换根DP就行了,(Ans[1]=dp[1])
那么考虑从某个父节点转移到子节点的过程,假设父节点为根的答案为(Ans[u])
那么我们先把子节点当成之前最后一个加入的,把他的影响刨去(假设剩下的子树集合为(S))
那么(S)的方案数(=frac{Ans[u]}{dp[v]*inom{n-1}{size[v]}})
那么下面考虑把(S)这部分插到(v)为根的里面,应该是(S)的方案数(*dp[v]*inom{n-1}{size[v]-1})
然后这就是(Ans[v])了
1 #include<bits/stdc++.h> 2 #define maxn 1000005 3 using namespace std; 4 const int mod = 1000000007; 5 int n; 6 vector<int> g[maxn]; 7 int fac[maxn],inv[maxn]; 8 int dp[maxn],sz[maxn],Ans[maxn]; 9 int fastpow(int a,int p) 10 { 11 int ans=1; 12 for(;p;p>>=1,a=1ll*a*a%mod)if(p&1)ans=1ll*ans*a%mod; 13 return ans; 14 } 15 int C(int x,int y) 16 { 17 return 1ll*fac[x]*inv[y]%mod*inv[x-y]%mod; 18 } 19 void dfs(int u,int f) 20 { 21 dp[u]=1; 22 for(int v:g[u])if(v!=f) 23 { 24 dfs(v,u); 25 dp[u]=1ll*dp[v]*dp[u]%mod*C(sz[u]+sz[v],sz[v])%mod; 26 sz[u]+=sz[v]; 27 } 28 sz[u]+=1; 29 } 30 void dfs2(int u,int f) 31 { 32 for(int v:g[u])if(v!=f) 33 { 34 //int t=1ll*Ans[u]*fastpow(dp[v],mod-2)%mod*fastpow(C(n-1,sz[v]),mod-2)%mod; 35 Ans[v]=1ll*Ans[u]*fastpow(C(n-1,sz[v]),mod-2)%mod*C(n-1,sz[v]-1)%mod; 36 dfs2(v,u); 37 } 38 } 39 int main() 40 { 41 fac[0]=inv[0]=1; 42 for(int i=1;i<=1000000;++i)fac[i]=1ll*fac[i-1]*i%mod,inv[i]=fastpow(fac[i],mod-2); 43 scanf("%d",&n); 44 for(int i=1;i<n;++i) 45 { 46 int u,v; 47 scanf("%d%d",&u,&v); 48 g[u].push_back(v);g[v].push_back(u); 49 } 50 dfs(1,0); 51 Ans[1]=dp[1]; 52 dfs2(1,0); 53 for(int i=1;i<=n;++i)printf("%d ",Ans[i]); 54 }
以上是关于Atcoder Beginner Contest 160 做题记录的主要内容,如果未能解决你的问题,请参考以下文章
AtCoder Beginner Contest 115 题解