• Educational Codeforces Round 58 Solution


    A. Minimum Integer

    签到。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 ll l, r, d;
     6 
     7 int main()
     8 {
     9     int t; scanf("%d", &t);
    10     while (t--)
    11     {
    12         scanf("%lld%lld%lld", &l, &r, &d);
    13         if (d < l) printf("%lld
    ", d);
    14         else printf("%lld
    ", ((r / d) + 1) * d);
    15     }
    16     return 0;
    17 }
    View Code

    B. Accordion

    签到。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 5000010
     5 char s[N];
     6 
     7 int work()
     8 {
     9     int l = -1, r = -1, flag, len = strlen(s + 1);
    10     flag = false;
    11     for (int i = 1; i <= len; ++i) 
    12     {
    13         if (s[i] == '[') flag = true; 
    14         else if (s[i] == ':' && flag) 
    15         {
    16             l = i;
    17             break;
    18         }
    19     } 
    20     if (l == -1) return -1;
    21     flag = false;
    22     for (int i = len; i >= 1; --i)
    23     {
    24         if (s[i] == ']') flag = true;
    25         else if (s[i] == ':' && flag)
    26         {
    27             r = i;
    28             break;
    29         }
    30     }
    31     if (r == -1) return -1;
    32     if (r <= l) return -1;
    33     int res = 4;
    34     for (int i = l + 1; i < r; ++i) if (s[i] == '|')
    35         ++res;
    36     return res;
    37 }
    38 
    39 int main()
    40 {
    41     while (scanf("%s", s + 1) != EOF)
    42         printf("%d
    ", work());
    43     return 0;
    44 }
    View Code

    C. Division and Union

    Solved.

    题意:

    有n个区间,将它分成两个集合,使得每个集合任意出一个区间组成的一对,这对没有交

    思路:

    按左端点排序,如果存在这样的划分,那么必定一个界限使得当前区间与之前的那个区间没有交,这样的话,后面的区间和之前的区间都不会有交

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 100010
     5 int t, n, ans[N];
     6 struct node
     7 {
     8     int l, r, id;
     9     void scan(int id) { scanf("%d%d", &l, &r); this->id = id; } 
    10     bool operator < (const node &other) const { return l < other.l || (l == other.l && r < other.r); }
    11 }a[N];
    12 
    13 int main()
    14 {
    15     scanf("%d", &t);
    16     while (t--)
    17     {
    18         scanf("%d", &n); 
    19         for (int i = 1; i <= n; ++i) a[i].scan(i);
    20         sort(a + 1, a + 1 + n);
    21         int pos = -1; int maxr = a[1].r;
    22         for (int i = 2; i <= n; ++i)
    23         {
    24             if (a[i].l > maxr)
    25             {
    26                 pos = i;
    27                 break; 
    28             }
    29             maxr = max(maxr, a[i].r);
    30         }
    31         if (pos == -1) puts("-1");
    32         else 
    33         {
    34             for (int i = 1; i <= n; ++i) ans[a[i].id] = i < pos ? 2 : 1;
    35             for (int i = 1; i <= n; ++i) printf("%d%c", ans[i], " 
    "[i == n]);
    36         }    
    37     }
    38     return 0;
    39 }
    View Code

    D. GCD Counting

    Upsolved.

    题意:

    一棵树中,每个点有权值,找出一条最长的简单路径,使得这个路劲上所有点的点权的gcd > 1

    思路:

    枚举质因子,再在虚树上dp

    质因子很多,有1w多个,但是我们考虑每个质因子对应的集合的总和不会太多,

    因为一个数的质因子个数不会太多,2e5一下也就十几个,那么一个数的贡献也就十几个

    最后的总和就是O(nlogn)级别的

    其实不用建虚树,直接在dfs序上dp就可以了

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 200010
     5 int n, a[N], res;
     6 vector <int> G[N];
     7 vector <int> fac[N];  
     8 
     9 int fa[N], p[N], pos[N], cnt; int f[2][N]; 
    10 void pre(int u)
    11 {
    12     p[u] = ++cnt;
    13     for (auto v : G[u]) if (v != fa[u])
    14     {
    15         fa[v] = u;
    16         pre(v);
    17     }
    18 }
    19 
    20 void init()
    21 {
    22     for (int i = 1; i <= n; ++i) G[i].clear();
    23     for (int i = 2; i < N; ++i) fac[i].clear();    
    24     memset(pos, -1, sizeof pos);
    25     res = 0; cnt = 0;
    26 }
    27 
    28 int main()
    29 {
    30     while (scanf("%d", &n) != EOF)
    31     {
    32         init();
    33         for (int i = 1; i <= n; ++i) scanf("%d", a + i);
    34         for (int i = 1, u, v; i < n; ++i)
    35         {
    36             scanf("%d%d", &u, &v);
    37             G[u].push_back(v);
    38             G[v].push_back(u);
    39         }
    40         pre(1);
    41         for (int i = 1; i <= n; ++i)
    42         {
    43             int tmp = a[i];
    44             int limit = sqrt(tmp);
    45             for (int j = 2; j <= limit; ++j)
    46             {
    47                 if (tmp % j == 0)
    48                 {
    49                     fac[j].push_back(i);
    50                     while (tmp % j == 0) tmp /= j;
    51                 }
    52             }
    53             if (tmp != 1) fac[tmp].push_back(i); 
    54         }
    55         for (int i = 2; i < N; ++i) if (fac[i].size() >= 1)
    56         {
    57             sort(fac[i].begin(), fac[i].end(), [](int x, int y) { return p[x] > p[y]; }); 
    58             int len = fac[i].size(); 
    59             for (int j = 0; j < len; ++j) for (int o = 0; o < 2; ++o) f[o][j] = 0;
    60             for (int j = 0; j < len; ++j) pos[fac[i][j]] = j;
    61             for (int j = 0, u, v; j < len; ++j) 
    62             {
    63                 v = fac[i][j];
    64                 res = max(res, f[0][j] + f[1][j] + 1);
    65                 if (pos[fa[v]] != -1) 
    66                 {
    67                     int id = pos[fa[v]];
    68                     if (f[0][j] + 1 >= f[0][id])
    69                     {
    70                         f[1][id] = f[0][id];
    71                         f[0][id] = f[0][j] + 1;
    72                     }
    73                     else if (f[0][j] + 1 >= f[1][id])
    74                     {
    75                         f[1][id] = f[0][j] + 1;
    76                     }
    77                 }
    78             }
    79             for (int j = 0; j < len; ++j) pos[fac[i][j]] = -1;
    80         }
    81         printf("%d
    ", res);
    82     }
    83     return 0;
    84 }
    View Code

    E. Polycarp's New Job

    签到.

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 500010
     5 int n, x, y, l, r; char op[10];
     6 
     7 int main()
     8 {
     9     l = 0, r = 0;
    10     scanf("%d", &n);
    11     while (n--)
    12     {
    13         scanf("%s%d%d", op, &x, &y);
    14         if (x > y) swap(x, y);
    15         if (op[0] == '+')
    16         {
    17             l = max(l, x);
    18             r = max(r, y);
    19         }
    20         else
    21         {
    22             puts(l <= x && r <= y ? "YES" : "NO");
    23         }
    24     }
    25     return 0;
    26 }
    View Code

    F. Trucks and Cities

    Upsolved.

    题意:

    $有n个城市,有m辆卡车需要从s_i -> f_i 每公里耗油c_i升,最多加油r_i次$

    $求最小的油箱体积,使得所有卡车都能在加油次数内到达目的地$

    思路:

    本来考虑二分$但是复杂度是O(n cdot m cdot log(10^{18}))$

    考虑$dp$

    $dp[i][j][k] 表示从i -> j 最多加油k次的最少油箱容量$

    $dp[i][j][k] = min_{w = i}^{j} max(dp[i][w][k - 1], a[j] - a[w])$

    我们发现 $dp[i][w][k - 1] 随着w递增而增加,a[j] - a[w] 随着w递增而减少$

    $但是,max(dp[i][w][k - 1], a[j] -a[w]) 是先减后增的$ 

    并且随着$j的右移动,决策点肯定只会向右移动,而不会回到左边$

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 #define N 401
     6 int n, m, a[N];
     7 int f[N][N][N];
     8 
     9 int main()
    10 {
    11     while (scanf("%d%d", &n, &m) != EOF)
    12     {
    13         for (int i = 1; i <= n; ++i) scanf("%d", a + i);
    14         memset(f, 0, sizeof f);
    15         for (int i = 1; i <= n; ++i)
    16             for (int j = 1; j <= n; ++j)
    17                 f[i][j][0] = a[j] - a[i];
    18         for (int k = 1; k <= n; ++k)
    19             for (int i = 1, w; i <= n; ++i)
    20             {
    21                 w = i;
    22                 for (int j = i + 1; j <= n; ++j) 
    23                 {
    24                     while (w < j && max(f[i][w + 1][k - 1], a[j] - a[w + 1]) <= max(f[i][w][k - 1], a[j] - a[w])) ++w;
    25                     f[i][j][k] = max(f[i][w][k - 1], a[j] - a[w]); 
    26                 }
    27             }
    28         ll res = 0;
    29         for (int i = 1, s, e, c, r; i <= m; ++i)
    30         {
    31             scanf("%d%d%d%d", &s, &e, &c, &r);
    32             res = max(res, 1ll * c * f[s][e][r]);
    33         }
    34         printf("%lld
    ", res);
    35     }
    36     return 0;
    37 }
    View Code

    G. (Zero XOR Subset)-less

    Upsolved.

    题意:

    将一些数分组,使得没有任意一个这些组的子集的异或和等于0

    思路:

    如果所有数异或起来等于$0$就是无解的情况

    否则就是线性基中基的个数,因为每个基的最高位的$1所在位置不同$

    $所以这些基不管怎么异或都不会是0$

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 200010
     5 int n, a[N], p[110];
     6 
     7 int main()
     8 {
     9     while (scanf("%d", &n) != EOF)
    10     {
    11         int t = 0;
    12         for (int i = 1; i <= n; ++i) scanf("%d", a + i), t ^= a[i];
    13         if (!t) puts("-1");
    14         else
    15         {
    16             memset(p, 0, sizeof p);
    17             for (int i = 1; i <= n; ++i)
    18                for (int j = 31; j >= 0; --j) 
    19                     if ((a[i] >> j) & 1)
    20                      {
    21                         if (!p[j]) 
    22                         {
    23                             p[j] = a[i];
    24                             break;
    25                         }
    26                         else a[i] ^= p[j];
    27                     }        
    28             int res = 0;
    29             for (int i = 0; i < 32; ++i) if (p[i]) ++res;
    30             printf("%d
    ", res);
    31         }
    32     }
    33     return 0;
    34 }
    View Code
  • 相关阅读:
    JavaScript event对象
    JavaScript Date对象
    JavasSript函数
    break语句补充:判断当前系统时间与2021年元旦相聚的天数
    JavaScript控制流程
    初识JavaSript-JavaScript主要特点,运用在HTML中的三种用法,基本语法
    一个简单的Java程序
    什么是Java语言规范、API、JDK和IDE
    Vue渐变淡入淡出的轮播图
    js获取窗口滚动条高度、窗口可视范围高度、文档实际内容高度、滚动条离浏览器底部的高度
  • 原文地址:https://www.cnblogs.com/Dup4/p/10258600.html
Copyright © 2020-2023  润新知