• CodeCraft-19 and Codeforces Round #537 (Div. 2)


    A. Superhero Transformation

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 1010
     5 char s[N], t[N], Hash[N];
     6 
     7 bool ok()
     8 {
     9     int n = strlen(s + 1);
    10     for (int i = 1; i <= n; ++i) 
    11         if (Hash[s[i]] != Hash[t[i]])
    12             return false;
    13     return true;
    14 }
    15 
    16 int main()
    17 {
    18     memset(Hash, 0, sizeof Hash);
    19     Hash['a'] = 1;
    20     Hash['e'] = 1;
    21     Hash['i'] = 1;
    22     Hash['o'] = 1;
    23     Hash['u'] = 1;
    24     while (scanf("%s%s", s + 1, t + 1) != EOF)
    25     {
    26         int len1 = strlen(s + 1), len2 = strlen(t + 1);
    27         if (len1 != len2) puts("No");
    28         else
    29             puts(ok() ? "Yes" : "No");
    30     }
    31     return 0;
    32 }
    View Code

    B. Average Superhero Gang Power

    Hacked.

    注意如果最大值不止一个,那么去掉几个是不一定的

    枚举即可。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 #define N 100010
     6 int n, k, m;
     7 ll a[N];
     8 
     9 int main()
    10 {
    11     while (scanf("%d%d%d", &n, &k, &m) != EOF)
    12     {
    13         for (int i = 1; i <= n; ++i) scanf("%lld", a + i);
    14         sort(a + 1, a + 1 + n);
    15         for (int i = 1; i <= n; ++i) a[i] += a[i - 1];
    16         double res = a[n] * 1.0 / n;
    17         for (int i = 0; i < n; ++i)
    18         {
    19             if (m < i) break;
    20             ll add = min(1ll * (m - i), 1ll * k * (n - i));
    21             res = max(res, (a[n] - a[i] + add) * 1.0 / (n - i));    
    22         }
    23         printf("%.10f
    ", res); 
    24     }
    25     return 0;
    26 }
    View Code

    C. Creative Snap

    递归求解即可,注意一整段空直接返回$A$

    这样最多只有$k个长度为1的节点被访问到$

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define ll long long
     5 #define N 
     6 int n, k, A, B;
     7 vector <int> v;
     8 
     9 ll CDQ(ll l, ll r)
    10 {
    11     if (r < l) return 0;
    12     int num = upper_bound(v.begin(), v.end(), r) - lower_bound(v.begin(), v.end(), l);
    13     if (num == 0) return A;  
    14     ll tmp = 1ll * (r - l + 1) * B * num;
    15     if (l == r) return tmp; 
    16     ll mid = (l + r) >> 1;
    17     return min(tmp, CDQ(l, mid) + CDQ(mid + 1, r));  
    18 }
    19 
    20 int main()
    21 {
    22     while (scanf("%d%d%d%d", &n, &k, &A, &B) != EOF)
    23     {
    24         v.clear();
    25         for (int i = 1, x; i <= k; ++i) 
    26         {
    27             scanf("%d", &x);
    28             v.push_back(x);
    29         }
    30         sort(v.begin(), v.end());
    31         printf("%lld
    ", CDQ(1, 1 << n)); 
    32     }
    33     return 0;
    34 }
    View Code

    D. Destroy the Colony

    Solved.

    题意:

    有$n个人,n为偶数, 每个人有一个种类$

    $询问给出x, y  要求将和第x人同种类并且和第y个人同种类的人放在一个集合$

    $并且挑选出一些人和他们放在一起,剩下的人在另一个集合$

    $要求两个集合人数相等,并且同一种类的人属于同个集合$

    $给出有多少种分配方式, 集合里是有顺序的,并且两个集合是不同的$ 

    思路:

    考虑一共有$f种方式将其他人和第x人同种类的人以及第y人同种类的人放在一个集合$

    $我们假定 第i种类的人有c_i个, 令m = frac{n}{2}$

    $那么答案就是 frac {m! cdot m! cdot f cdot 2}{c_1! cdot c_2! cdots}$

    那么考虑怎么处理$f, 可以用背包,但是暴力预处理时间复杂度是O(52^{3} cdot n)$

    $但是我们可以先处理好总的,注意到对于每种情况的处理只有最多两项物品的删除$

    $直接删除方案数即可 这样时间复杂度就是O(52^{2} cdot n)$

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define ll long long
      5 #define N 100010
      6 const ll MOD = (ll)1e9 + 7;
      7 char s[N];
      8 int cnt[110], Hash[210];
      9 int n, q, x, y, mid;
     10 ll fac[N], inv[N];
     11 ll f[110][110]; 
     12 ll g[N]; 
     13 
     14 ll qmod(ll base, ll n)
     15 {
     16     ll res = 1;
     17     while (n)
     18     {
     19         if (n & 1) res = res * base % MOD;
     20         base = base * base % MOD;
     21         n >>= 1;
     22     }
     23     return res;
     24 }
     25 
     26 ll C(int n, int m)
     27 {
     28     return fac[n] * inv[m] % MOD * inv[n - m] % MOD;
     29 }
     30 
     31 int main()
     32 {
     33     fac[0] = 1;
     34     for (int i = 1; i <= 100000; ++i) fac[i] = (fac[i - 1] * i) % MOD;
     35     inv[100000] = qmod(fac[100000], MOD - 2);
     36     for (int i = 100000; i >= 1; --i) inv[i - 1] = (inv[i] * i) % MOD;
     37     for (int i = 1; i <= 26; ++i) Hash['a' + i - 1] = i;
     38     for (int i = 27; i <= 52; ++i) Hash['A' + i - 27] = i; 
     39     while (scanf("%s", s + 1) != EOF)
     40     {
     41         n = strlen(s + 1);
     42         mid = n / 2;
     43         memset(cnt, 0, sizeof cnt);
     44         for (int i = 1; i <= n; ++i) ++cnt[Hash[s[i]]];
     45         ll tmp = 1; 
     46         for (int i = 1; i <= 52; ++i) 
     47             if (cnt[i]) tmp = (tmp * inv[cnt[i]]) % MOD;
     48         memset(f, 0, sizeof f);
     49         memset(g, 0, sizeof g); 
     50         g[0] = 1;
     51         for (int i = 1; i <= 52; ++i) if (cnt[i])
     52         {
     53             for (int j = mid; j >= cnt[i]; --j)
     54                 g[j] += g[j - cnt[i]];
     55         } 
     56         for (int i = 1; i <= 52; ++i)
     57         {
     58             for (int j = i + 1; j <= 52; ++j)
     59             {
     60                 if (cnt[i] == 0 || cnt[j] == 0) continue;
     61                 if (cnt[i] + cnt[j] > mid) continue;
     62                 if (cnt[i] + cnt[j] == mid)
     63                 {
     64                     f[i][j] = f[j][i] = 1;
     65                     continue;
     66                 }
     67                 for (int k = cnt[i]; k <= mid; ++k)
     68                     g[k] -= g[k - cnt[i]];
     69                 for (int k = cnt[j]; k <= mid; ++k)
     70                     g[k] -= g[k - cnt[j]];
     71                 f[i][j] = f[j][i] = g[mid - cnt[i] - cnt[j]] % MOD;
     72                 //printf("%d %d %lld
    ", i, j, f[i][j]);
     73                 for (int k = mid; k >= cnt[i]; --k)
     74                     g[k] += g[k - cnt[i]];
     75                 for (int k = mid; k >= cnt[j]; --k)
     76                     g[k] += g[k - cnt[j]];
     77             }
     78         }
     79         for (int i = 1; i <= 52; ++i) if (cnt[i] && cnt[i] <= mid) 
     80         {
     81             for (int j = cnt[i]; j <= mid; ++j)
     82                 g[j] -= g[j - cnt[i]];
     83             f[i][i] = g[mid - cnt[i]] % MOD;
     84             //printf("%d %lld
    ", i, f[i][i]);
     85             //printf("%d %d %lld
    ", i, i, f[i][i]);
     86             for (int j = mid; j >= cnt[i]; --j)
     87                 g[j] += g[j - cnt[i]];
     88         }
     89         //for (int i = 1; i <= mid; ++i) printf("%lld%c", g[i], " 
    "[i == mid]);
     90         scanf("%d", &q);
     91         while (q--)
     92         {
     93             scanf("%d%d", &x, &y);
     94             //cout << f[Hash[s[x]]][Hash[s[y]]] << endl;
     95             ll res = fac[mid] * fac[mid] % MOD * 2 % MOD * tmp % MOD * f[Hash[s[x]]][Hash[s[y]]] % MOD; 
     96             printf("%lld
    ", res);
     97         }
     98     }
     99     return 0;
    100 }
    View Code

    E. Tree

    Upsolved.

    题意:

    在一棵树上

    $每次询问给出一些点,根节点r以及组数m$

    $要求将所有点分配到一个组中,最多分成m组,要求同一组的点任意两点不能是祖先关系$

    $给出分配方案数$

    思路:

    考虑假如根节点是$1$

    $dp[i][j] 表示到第i个点放进j个集合的方案数$

    $首先要将点按DFS序排序 令f[i] 表示 i这个点有多少祖先在这里$

    $dp[i][j] = dp[i - 1][j] * (j - f[i]) + dp[i - 1][j - 1]$

    那么我们再考虑根节点任意的情况

    $其实原来多少祖先就是点到1的路径上有多少点出现过$

    $那么根节点任意的话 就是当前点到根节点的简单路径有多少点出现过$

    $按照这个排序,就可以不重不漏的统计$

    $维护节点出现个数 可以用DFS序+BIT 维护$

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define ll long long 
      5 #define N 100010
      6 const ll MOD = (ll)1e9 + 7;
      7 int n, q;
      8 vector <int> G[N];
      9 int f[N], vec[N], mark[N];
     10 ll dp[1010]; 
     11 
     12 int top[N], fa[N], deep[N], sze[N], son[N], lp[N], rp[N], cnt;
     13 void DFS(int u)
     14 {
     15     sze[u] = 1;
     16     for (auto v : G[u]) if (v != fa[u])
     17     {
     18         fa[v] = u;
     19         deep[v] = deep[u] + 1;
     20         DFS(v);
     21         sze[u] += sze[v];
     22         if (!son[u] || sze[v] > sze[son[u]]) son[u] = v; 
     23     }
     24 }
     25 
     26 void gettop(int u, int sp)
     27 {
     28     top[u] = sp;
     29     lp[u] = ++cnt;
     30     if (!son[u])
     31     {
     32         rp[u] = cnt;
     33         return;
     34     }
     35     gettop(son[u], sp);
     36     for (auto v : G[u]) if (v != fa[u] && v != son[u])
     37         gettop(v, v);
     38     rp[u] = cnt;
     39 }
     40 
     41 int lca(int u, int v)
     42 {
     43     while (top[u] != top[v])
     44     {
     45         if (deep[top[u]] < deep[top[v]]) swap(u, v);
     46         u = fa[top[u]];
     47     }
     48     if (deep[u] > deep[v]) swap(u, v);
     49     return u;
     50 }
     51 
     52 namespace BIT
     53 {
     54     int a[N];
     55     void init() { memset(a, 0, sizeof a); }
     56     void update(int x, int val)
     57     {
     58         for (; x < N; x += x & -x)
     59             a[x] += val;
     60     }
     61     int query(int x)
     62     {
     63         int res = 0;
     64         for (; x > 0; x -= x & -x)
     65             res += a[x];
     66         return res;
     67     }
     68     void update(int l, int r, int val)
     69     {
     70         update(l, val);
     71         update(r + 1, -val);
     72     }
     73 };
     74 
     75 int main()
     76 {
     77     while (scanf("%d%d", &n, &q) != EOF)
     78     {
     79         for (int i = 1; i <= n; ++i) G[i].clear();
     80         memset(mark, 0, sizeof mark);
     81         memset(son, 0, sizeof son);    
     82         cnt = 0;
     83         BIT::init();
     84         for (int i = 1, u, v; i < n; ++i) 
     85         {
     86             scanf("%d%d", &u, &v);
     87             G[u].push_back(v);
     88             G[v].push_back(u);
     89         }
     90         DFS(1); gettop(1, 1);
     91         int k, m, r;
     92         while (q--)
     93         {
     94             scanf("%d%d%d", &k, &m, &r);
     95             for (int i = 0; i <= m; ++i) dp[i] = 0; dp[0] = 1;
     96             for (int i = 1; i <= k; ++i) 
     97                 scanf("%d", vec + i);
     98             for (int i = 1; i <= k; ++i)
     99             {
    100                 int x = vec[i]; 
    101                 mark[x] = 1; 
    102                 BIT::update(lp[x], rp[x], 1);
    103             }
    104             int ans_root = BIT::query(lp[r]);
    105             for (int i = 1; i <= k; ++i)
    106             {
    107                 int x = vec[i];
    108                 int y = lca(x, r);
    109                 f[x] = BIT::query(lp[x]) + ans_root - 2 * BIT::query(lp[y]) + (mark[y] == 1) - 1;
    110             }
    111             for (int i = 1; i <= k; ++i)
    112             {
    113                 int x = vec[i];
    114                 mark[x] = 0;
    115                 BIT::update(lp[x], rp[x], -1);
    116             }
    117             sort(vec + 1, vec + 1 + k, [](int x, int y) 
    118             {
    119                 return f[x] < f[y];             
    120             });
    121             if (f[vec[k]] >= m) puts("0");
    122             else
    123             {
    124                 for (int i = 1; i <= k; ++i)
    125                 {
    126                     int x = vec[i];
    127                     for (int j = min(i, m); j >= 0; --j)
    128                     {
    129                         if (j <= f[x]) dp[j] = 0;
    130                         else
    131                             dp[j] = (1ll * dp[j] * (j - f[x]) % MOD + dp[j - 1]) % MOD;
    132                     }
    133                 }
    134                 ll ans = 0;
    135                 for (int i = 1; i <= m; ++i) ans = (ans + dp[i]) % MOD;
    136                 printf("%lld
    ", ans);
    137             }    
    138         }
    139     }
    140     return 0;
    141 }
    View Code
  • 相关阅读:
    css3文字单位rem 设置文字大小
    JS实现多物体width缓冲运动实例
    vs 你不得不会的调试方式
    C# 常用修饰符
    富文本编辑器tinymce
    Swagger简单实例
    marquee标签详解
    table数据跑马灯效果
    SqlServer发布订阅
    ORM概述及常用ORM框架
  • 原文地址:https://www.cnblogs.com/Dup4/p/10351424.html
Copyright © 2020-2023  润新知