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

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 }

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

时间: 2024-11-04 21:24:33

Atcoder Beginner Contest 160 做题记录的相关文章

AtCoder Beginner Contest 160题解

A. 签到题1. #include<bits/stdc++.h> #define fi first #define sd second #define lson (nd<<1) #define rson (nd+nd+1) #define PB push_back #define mid (l+r>>1) #define MP make_pair #define SZ(x) (int)x.size() using namespace std; typedef long

AtCoder Beginner Contest 116 C题 【题意:可以在任意区间【L,R】上加1,求通过最少加1次数得到题目给定的区间】】{思维好题}

C - Grand Garden In a flower bed, there are NN flowers, numbered 1,2,......,N1,2,......,N. Initially, the heights of all flowers are 00. You are given a sequence h={h1,h2,h3,......}h={h1,h2,h3,......} as input. You would like to change the height of

AtCoder Beginner Contest 160

传送门 A - Coffee #include <bits/stdc++.h> #define ll long long using namespace std; char s[10]; int main() { //freopen("in.txt","r",stdin); scanf("%s",s); if(s[2]==s[3]&&s[4]==s[5]) printf("Yes\n"); else

【ATcoder】AtCoder Beginner Contest 161 题解

题目链接:AtCoder Beginner Contest 161 原版题解链接:传送门 A - ABC Swap 这题太水,直接模拟即可. 1 #include <iostream> 2 using namespace std; 3 int main() { 4 int a, b, c; 5 cin >> a >> b >> c; 6 swap(a, b); 7 swap(a, c); 8 cout << a << " &

AtCoder Beginner Contest 136

AtCoder Beginner Contest 136 Contest Duration : 2019-08-04(Sun) 20:00 ~ 2019-08-04(Sun) 21:40 Website: AtCoder BC-136 后面几题都挺考思考角度D. C - Build Stairs 题目描述: 有n座山从左到右排列,给定每一座山的高度\(Hi\),现在你可以对每座山进行如下操作至多一次:将这座山的高度降低1. 问是否有可能通过对一些山进行如上操作,使得最后从左至右,山的高度呈不下降

AtCoder Beginner Contest 154 题解

人生第一场 AtCoder,纪念一下 话说年后的 AtCoder 比赛怎么这么少啊(大雾 AtCoder Beginner Contest 154 题解 A - Remaining Balls We have A balls with the string S written on each of them and B balls with the string T written on each of them. From these balls, Takahashi chooses one

AtCoder Beginner Contest 155 简要题解

AtCoder Beginner Contest 155 A:签到失败,WA一次. int main() { int a, b, c; cin >> a >> b >> c; if(a == b && b == c) cout << "No"; else if(a == b || a == c || b == c) cout << "Yes"; else cout << &quo

【BZOJ做题记录】07.07~?

在NOI一周前重开一个坑 最后更新时间:7.07 11:26 7.06 下午做的几道CQOI题: BZOJ1257: [CQOI2007]余数之和sum:把k mod i写成k-k/i*i然后分段求后面的部分就好了 BZOJ1258: [CQOI2007]三角形tri:在草稿纸上按照位置和边找一下规律就好了 BZOJ1260: [CQOI2007]涂色paint:简单的区间DP BZOJ1303: [CQOI2009]中位数图:小于中位数的改为-1大于的改为1,算一算前缀和然后哈希一下乘一乘就好

AtCoder Beginner Contest 103 D(贪心)

AtCoder Beginner Contest 103 D 题目大意:n个点,除第n个点外第i与第i+1个点有一条边,给定m个a[i],b[i],求最少去掉几条边能使所有a[i],b[i]不相连. 按右端点从小到大排序,如果当前选的去掉的边在区间内,那么符合条件,否则ans++,并贪心地把去掉的边指向右端点,因为前面的区间都满足条件了,所以要去掉的边要尽量向右移使其满足更多的区间. 1 #include <iostream> 2 #include <cstdio> 3 #incl