码迷,mamicode.com
首页 > 其他好文 > 详细

Atcoder Beginner Contest 160 做题记录

时间:2020-03-30 09:25:08      阅读:84      评论:0      收藏:0      [点我收藏+]

标签:while   cto   树形dp   front   class   clu   const   题记   can   

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 }
View Code

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\n",1000*A+C*5);
10 }
View Code

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\n",ans);
12 }
View Code

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\n",Ans[i]/2);
25 }
View Code

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\n",ans); 
55 }
View Code

F.

考虑以\(1\)为出发点怎么计数:我们可以通过一次树形DP来计数

\(dp[u]\)表示\(u\)的子树中的方案数

我们枚举子树\(v\),考虑将\(v\)插入到之前遍历过的子树点集\(S\)中(初始为空),\(S\)中的方案数为暂时的\(dp[u]\)(初始为\(1\))

那么显然有\(dp[u]=dp[u]*dp[v]*\binom{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]*\binom{n-1}{size[v]}}\)

那么下面考虑把\(S\)这部分插到\(v\)为根的里面,应该是\(S\)的方案数\(*dp[v]*\binom{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\n",Ans[i]); 
54 }
View Code

 

Atcoder Beginner Contest 160 做题记录

标签:while   cto   树形dp   front   class   clu   const   题记   can   

原文地址:https://www.cnblogs.com/uuzlove/p/12596430.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!