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

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

 

以上是关于Atcoder Beginner Contest 160 做题记录的主要内容,如果未能解决你的问题,请参考以下文章

AtCoder Beginner Contest 234

AtCoder Beginner Contest 115 题解

AtCoder Beginner Contest 154 题解

AtCoder Beginner Contest 103

AtCoder Beginner Contest 228

AtCoder Beginner Contest 242