• Codeforces Edu Round 64 (Rated for Div. 2)


    本来在快乐写题的,突然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
    ", 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
    ", 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
    ", solve(0, n));
    75     return 0;
    76 }
    View Code

    F && G:

    太神仙了……再见

  • 相关阅读:
    联考20200725 T1 String
    联考20200723 T1 数
    联考20200722 T3 积木
    联考20200722 T2 ACT4!无限回转!
    联考20200722 T1 集合划分
    联考20200721 T2 s2mple
    联考20200721 T1 s1mple
    联考20200719 T2 寻找规律
    联考20200719 T1 合并奶牛
    联考20200718 T2 树论
  • 原文地址:https://www.cnblogs.com/JHSeng/p/10803378.html
Copyright © 2020-2023  润新知