1. 程式人生 > >Codeforces Round #548 (Div. 2) ABC 題解

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

tor cin %d color scanf ems event bstr esp

題目鏈接

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

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