Codeforces Round #548 (Div. 2) ABC 题解

题目链接

A. Even Substrings

分析

当输入第i个数的时候,判断一下是不是偶数,若是偶数的话ans+=i,以这个数为r的子串有i个,最后统计出来的ans就是答案.

代码

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <string>
 8 #include <utility>
 9 #include <queue>
10 #include <stack>
11 #include <map>
12 #include <set> 
13 using namespace std;
14 const int INF=0x3f3f3f3f; 
15 
16 typedef long long LL;
17 
18 int main()
19 {
20 //    freopen("in.txt","r",stdin);
21 //    freopen("out.txt","w",stdout);
22     int n;
23     cin>>n;
24     getchar();
25     long long ans=0;
26     for(int i=0;i<n;i++)
27     {
28         char x;
29         scanf("%c",&x);
30         if(!((x-'0')&1)) ans+=i+1;
31     }
32     cout<<ans<<endl;
33     return 0;
34 }                 
View Code

B. Chocolates

分析

若要买的巧克力最多,那第n-1种巧克力必定买an-1个,然后往前遍历,若a[i]>=a[i+1],则令a[i]=a[i+1]-1,ans+=a[i],否则ans+=a[i],这里注意一下当a[i+1]=0时,前面i种巧克力必定都没买,于是有if(!a[i+1]) break;i从n-1往前遍历一遍,ans就是答案.

代码

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <string>
 8 #include <utility>
 9 #include <queue>
10 #include <stack>
11 #include <map>
12 #include <set> 
13 using namespace std;
14 const int INF=0x3f3f3f3f; 
15 
16 typedef long long LL;
17 
18 int a[200001];
19 
20 int main()
21 {
22 //    freopen("in.txt","r",stdin);
23 //    freopen("out.txt","w",stdout);
24     int n;
25     cin>>n;
26     for(int i=0;i<n;i++) scanf("%d",&a[i]);
27     long long ans=0;
28     for(int i=n-1;i>=0;i--)
29     {
30         if(i==n-1) ans+=a[i];
31         else
32         {
33             if(!a[i+1]) break;
34             if(a[i]>=a[i+1])
35             {
36                 a[i]=a[i+1]-1;
37                 ans+=a[i];
38             }
39             else ans+=a[i];
40         }
41     }
42     cout<<ans<<endl;
43     return 0;
44 }                 
View Code

C. Edgy Trees

分析

正难则反,可以先不去考虑黑边,对于给出的一幅图,只需要找出所有极大红边子图分块(该子图只有红边),然后由这个子图的顶点构成的k序列必定不是good序列.设第i个极大红边子图由u个顶点,可知有uk个序列不是good的.求出每个极大红边子图的序列值(uk)之和,记为ans,然后ans=nk-ans-(不在极大红边子图分块里的点的数量),由相同点构成的序列也不是good序列,所以还得减去最后一部分.找极大红边子图分块用dfs扫,求ab%mod用快速幂求.

代码

 1 #include <cstdio>
 2 #include <cmath>
 3 #include <iostream>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <string>
 8 #include <utility>
 9 #include <queue>
10 #include <stack>
11 #include <map>
12 #include <set> 
13 using namespace std;
14 const int INF=0x3f3f3f3f; 
15 
16 const int mod=1e9+7;
17 vector<int> es[100001];
18 vector<int> w;
19 bool vis[100001];
20 
21 int dfs(int s,int cnt)
22 {
23     if(vis[s]) return cnt;
24     vis[s]=true,cnt++;
25     for(int i=0;i<es[s].size();i++)
26     cnt=dfs(es[s][i],cnt);
27     return cnt;
28 }
29 
30 long long power(long long a,int b)
31 {
32     long long ans=1;
33     while(b)
34     {
35         if(b&1) ans=ans*a%mod;
36         a=a*a%mod;
37         b>>=1;
38     }
39     return ans;
40 }
41 
42 int main()
43 {
44 //    freopen("in.txt","r",stdin);
45 //    freopen("out.txt","w",stdout);
46     int n,k;
47     cin>>n>>k;
48     for(int i=0;i<n-1;i++)
49     {
50         int u,v,c;
51         scanf("%d %d %d",&u,&v,&c);
52         if(!c)
53         {
54             if(!vis[u]) w.push_back(u),vis[u]=true;
55             es[u].push_back(v);
56             es[v].push_back(u);
57         }
58     }
59     memset(vis,false,sizeof(vis));
60     long long ans=0;
61     for(int i=0;i<w.size();i++)
62     if(!vis[w[i]])
63     {
64         long long t=dfs(w[i],0);
65         ans=(ans+power(t,k))%mod;
66     }
67     if(power(n,k)-ans<0) ans=power(n,k)-ans+mod;
68     else ans=power(n,k)-ans;
69     for(int i=1;i<=n;i++)
70     if(!vis[i]) ans-=1;
71     cout<<ans<<endl;
72     return 0;
73 }                 
View Code

猜你喜欢

转载自www.cnblogs.com/VBEL/p/10699008.html