1. 程式人生 > >Codeforces Edu Round 64 (Rated for Div. 2)

Codeforces Edu Round 64 (Rated for Div. 2)

tac vector amp ++ none ins cstring make mat

本來在快樂寫題的,突然A數據炸了,全場重測,unrated……

昨晚的題也有點毒,不過總體來說還算簡單。


A:

一開始我也wa on 3了,仔細想想就會發現有重點的情況。

比如n==3, 3 1 2。答案應該是6而不是7。

技術分享圖片
 1 /* basic header */
 2 #include <bits/stdc++.h>
 3 /* define */
 4 #define ll long long
 5 #define dou double
 6 #define pb emplace_back
 7 #define mp make_pair
 8
#define fir first 9 #define sec second 10 #define sot(a,b) sort(a+1,a+1+b) 11 #define rep1(i,a,b) for(int i=a;i<=b;++i) 12 #define rep0(i,a,b) for(int i=a;i<b;++i) 13 #define repa(i,a) for(auto &i:a) 14 #define eps 1e-8 15 #define int_inf (1<<30)-1 16 #define ll_inf (1LL<<62)-1 17
#define lson curPos<<1 18 #define rson (curPos<<1)+1 19 /* namespace */ 20 using namespace std; 21 /* header end */ 22 23 int n, last = 0, ans = 0, flag = 1, llast = 0; 24 25 int main() 26 { 27 scanf("%d%d", &n, &last); 28 n--; 29 for (int i = 1; i <= n; i++)
30 { 31 int x; 32 scanf("%d", &x); 33 if (last == 1) 34 { 35 if (x == 1) 36 { 37 flag = 0; 38 } 39 else if (x == 2) 40 { 41 if (llast + last == 4) 42 ans += 2; 43 else 44 ans += 3; 45 } 46 else if (x == 3) 47 ans += 4; 48 } 49 else if (last == 2) 50 { 51 if (x == 2) 52 { 53 ans += 3; 54 } 55 else if (x == 1) 56 ans += 3; 57 else if (x == 3) 58 { 59 flag = 0; 60 } 61 } 62 else if (last == 3) 63 { 64 if (x == 3) 65 { 66 ans += 4; 67 } 68 else if (x == 1) 69 ans += 4; 70 else if (x == 2) 71 { 72 flag = 0; 73 } 74 } 75 if (i >= 1) 76 llast = last; 77 last = x; 78 } 79 if (!flag) 80 puts("Infinite"); 81 else 82 { 83 puts("Finite"); 84 printf("%d\n", ans); 85 } 86 return 0; 87 }
View Code

B:

各種寫法都有。這題可以寫得非常短。按字母在字母表的下標奇偶性來分類就好了。

然而我覺得取字母集合,sort一下再next_permutation+剪枝也可以,就是沒有分類這種寫法優秀。

技術分享圖片
 1 #include <bits/stdc++.h>
 2 
 3 using namespace std;
 4 
 5 const int maxn = 1e2 + 10;
 6 
 7 void print(char *a, int len)
 8 {
 9     for (int i = 1; i <= len; i++) printf("%c", a[i]);
10 }
11 
12 int main()
13 {
14     int t; scanf("%d", &t);
15     while (t--)
16     {
17         char s[maxn], a[maxn], b[maxn];
18         scanf("%s", s + 1); int len = strlen(s + 1), p = 0, q = 0;
19         sort(s + 1, s + 1 + len);
20         for (int i = 1; i <= len; i++)
21                 if (s[i] & 1) a[++p] = s[i]; else b[++q] = s[i];
22         if (!p || !q)
23         {
24             print(a, p); print(b, q);
25         }
26         else if (abs(a[p] - b[1]) != 1)
27         {
28             print(a, p); print(b, q);
29         }
30         else if (abs(b[q] - a[1]) != 1)
31         {
32             print(b, q); print(a, p);
33         }
34         else printf("No answer");
35         puts("");
36     }
37     return 0;
38 }
View Code

C:

很容易就想到二分。

技術分享圖片
 1 /* basic header */
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <cstdint>
 9 #include <climits>
10 #include <float.h>
11 /* STL */
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <queue>
16 #include <stack>
17 #include <algorithm>
18 #include <array>
19 #include <iterator>
20 /* define */
21 #define ll long long
22 #define dou double
23 #define pb emplace_back
24 #define mp make_pair
25 #define fir first
26 #define sec second
27 #define sot(a,b) sort(a+1,a+1+b)
28 #define rep1(i,a,b) for(int i=a;i<=b;++i)
29 #define rep0(i,a,b) for(int i=a;i<b;++i)
30 #define repa(i,a) for(auto &i:a)
31 #define eps 1e-8
32 #define int_inf (1<<30)-1
33 #define ll_inf (1LL<<62)-1
34 #define lson curPos<<1
35 #define rson (curPos<<1)+1
36 /* namespace */
37 using namespace std;
38 /* header end */
39 
40 const int maxn = 2e5 + 10;
41 int n, z, a[maxn];
42 
43 int main()
44 {
45     scanf("%d%d", &n, &z);
46     for (int i = 0; i < n; i++) scanf("%d", &a[i]);
47     sort(a, a + n);
48     int l = 0, r = n / 2 + 1;
49     while (r - l > 1)
50     {
51         int mid = l + r >> 1, sign = 1;
52         for (int i = 0; i < mid; i++)
53             sign &= (a[n - mid + i] - a[i] >= z);
54         if (sign) l = mid; else r = mid;
55     }
56     printf("%d\n", l);
57     return 0;
58 }
View Code

D:

有點像是字典樹,匹配文法規則為0*1*的字符串。

樹上dp,也可以DSU過。

技術分享圖片
 1 /* basic header */
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <cstdint>
 9 #include <climits>
10 #include <float.h>
11 /* STL */
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <queue>
16 #include <stack>
17 #include <algorithm>
18 #include <array>
19 #include <iterator>
20 /* define */
21 #define ll long long
22 #define dou double
23 #define pb emplace_back
24 #define mp make_pair
25 #define fir first
26 #define sec second
27 #define sot(a,b) sort(a+1,a+1+b)
28 #define rep1(i,a,b) for(int i=a;i<=b;++i)
29 #define rep0(i,a,b) for(int i=a;i<b;++i)
30 #define repa(i,a) for(auto &i:a)
31 #define eps 1e-8
32 #define int_inf 0x3f3f3f3f
33 #define ll_inf 0x7f7f7f7f7f7f7f7f
34 #define lson curPos<<1
35 #define rson curPos<<1|1
36 /* namespace */
37 using namespace std;
38 /* header end */
39 
40 const int maxn = 2e5 + 10;
41 
42 int n, dp[2][maxn];
43 vector<pair<int, int>> graph[maxn];
44 ll ans;
45 
46 void calc(int u, pair<int, int> v, int mt)
47 {
48     if (!v.second)
49         dp[0][u] += mt * dp[0][v.first];
50     else
51         dp[1][u] += mt * dp[0][v.first] + mt * dp[1][v.first];
52 }
53 
54 void dfs1(int u, int p)
55 {
56     for (pair<int, int> v : graph[u])
57     {
58         if (v.first == p)
59             continue;
60         dfs1(v.first, u);
61         calc(u, v, 1);
62     }
63     ans += dp[0][u] + dp[1][u];
64     dp[0][u]++;
65 }
66 
67 void dfs2(int u, int p, int pp1, int pp2)
68 {
69     ans += pp1 + pp2;
70     for (pair<int, int> v : graph[u])
71     {
72         if (v.first == p)
73             continue;
74         calc(u, v, -1);
75         if (!v.second)
76             dfs2(v.first, u, pp1 + dp[0][u], 0);
77         else
78             dfs2(v.first, u, 0, pp1 + pp2 + dp[0][u] + dp[1][u]);
79         calc(u, v, 1);
80     }
81 }
82 
83 int main()
84 {
85     scanf("%d", &n);
86     for (int i = 1, u, v, c; i < n; i++)
87     {
88         scanf("%d%d%d", &u, &v, &c); --u; --v;
89         graph[u].pb(mp(v, c));
90         graph[v].pb(mp(u, c));
91     }
92     dfs1(0, -1); dfs2(0, -1, 0, 0);
93     cout << ans << endl;
94     return 0;
95 }
View Code

E:

看了rk1大佬的代碼才意識到可以二分做。時間復雜度約等於O(NlogN)。

技術分享圖片
 1 /* basic header */
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstdlib>
 5 #include <string>
 6 #include <cstring>
 7 #include <cmath>
 8 #include <cstdint>
 9 #include <climits>
10 #include <float.h>
11 /* STL */
12 #include <vector>
13 #include <set>
14 #include <map>
15 #include <queue>
16 #include <stack>
17 #include <algorithm>
18 #include <array>
19 #include <iterator>
20 /* define */
21 #define ll long long
22 #define dou double
23 #define pb emplace_back
24 #define mp make_pair
25 #define fir first
26 #define sec second
27 #define sot(a,b) sort(a+1,a+1+b)
28 #define rep1(i,a,b) for(int i=a;i<=b;++i)
29 #define rep0(i,a,b) for(int i=a;i<b;++i)
30 #define repa(i,a) for(auto &i:a)
31 #define eps 1e-8
32 #define int_inf (1<<30)-1
33 #define ll_inf (1LL<<62)-1
34 #define lson curPos<<1
35 #define rson (curPos<<1)+1
36 /* namespace */
37 using namespace std;
38 /* header end */
39 
40 const int maxn = 2e5 + 10;
41 int a[maxn], n;
42 
43 ll solve(int l, int r)
44 {
45     if (r - l == 1) return 0;
46     int mid = l + r >> 1;
47     ll ret = solve(l, mid) + solve(mid, r); //避免處理長度為1的區間
48     {
49         set<int>s;
50         //把p當做區間的左端點&&最大值,往右擴展。下法同理。
51         for (int i = mid - 1, j = mid, p = 0; i >= l; i--)
52         {
53             p = max(p, a[i]);
54             while (j < r && a[j] < p) s.insert(a[j++]);
55             ret += s.count(p - a[i]);
56         }
57     }
58     {
59         set<int>s;
60         for (int i = mid, j = mid - 1, p = 0; i < r; i++)
61         {
62             p = max(p, a[i]);
63             while (j >= l && a[j] < p) s.insert(a[j--]);
64             ret += s.count(p - a[i]);
65         }
66     }
67     return ret;
68 }
69 
70 int main()
71 {
72     scanf("%d", &n);
73     rep0(i, 0, n) scanf("%d", &a[i]);
74     printf("%lld\n", solve(0, n));
75     return 0;
76 }
View Code

F && G:

太神仙了……再見

Codeforces Edu Round 64 (Rated for Div. 2)