zoukankan      html  css  js  c++  java
  • 牛客国庆集训派对Day3 Solution

    A    Knight

    留坑。

    B    Tree

    思路:两次树形DP,但是要考虑0没有逆元

    可以用前缀后缀做

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3  
     4 #define N 1000010
     5 #define ll long long
     6  
     7 const ll MOD = (ll)1e9 + 7;
     8  
     9  
    10 int n;
    11 ll dp[N], dp2[N];
    12 ll prefix[N], suffix[N];
    13 vector <int> G[N]; 
    14  
    15 void Init()
    16 {
    17     for (int i = 1; i <= n; ++i) dp[i] = 1, dp2[i] = 0, G[i].clear();
    18 }
    19  
    20 void DFS(int u, int fa)
    21 {
    22     for (auto v : G[u])
    23     {
    24         if (v == fa) continue;
    25         DFS(v, u);
    26         dp[u] = dp[u] * (dp[v] + 1) % MOD;
    27     }
    28 }
    29  
    30 void DFS2(int u, int fa)
    31 {
    32     prefix[0] = 1;
    33     suffix[G[u].size() + 1] = 1;
    34     int len = G[u].size();
    35     for (int i = 0; i < len; ++i)
    36     {
    37         int v = G[u][i];
    38         if (v == fa) prefix[i + 1] = prefix[i];
    39         else prefix[i + 1] = prefix[i] * (dp[G[u][i]] + 1) % MOD;
    40     }
    41     for (int i = len - 1; i >= 0; --i)
    42     {
    43         int v = G[u][i];
    44         if (v == fa) suffix[i + 1] = suffix[i + 2];
    45         else suffix[i + 1] = suffix[i + 2] * (dp[G[u][i]] + 1) % MOD;
    46  
    47     }
    48     for (int i = 0; i < len; ++i) 
    49     {
    50         int v = G[u][i];
    51         if (v == fa) continue; 
    52         dp2[v] = prefix[i] % MOD * suffix[i + 2] % MOD * (dp2[u] + 1) % MOD; 
    53     }
    54     for (auto v : G[u])
    55     {
    56         if (v == fa) continue;
    57         DFS2(v, u);
    58     }
    59 }
    60  
    61 void Run()
    62 {
    63     while (scanf("%d", &n) != EOF)
    64     {
    65         Init();
    66         for (int i = 1, u, v; i < n; ++i)
    67         {
    68             scanf("%d%d", &u, &v);
    69             G[u].push_back(v);
    70             G[v].push_back(u);
    71         }
    72         DFS(1, 0); DFS2(1, 0);
    73         for (int i = 1; i <= n; ++i) printf("%lld
    ", dp[i] * (dp2[i] + 1) % MOD);
    74     }
    75 }
    76  
    77 int main()
    78 {
    79     #ifdef LOCAL
    80         freopen("Test.in", "r", stdin);
    81     #endif
    82  
    83     Run();
    84     return 0;
    85 }
    View Code

    C    Two Graphs

    留坑。

    D    Shopping

    贪心即可。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 1010
     5 
     6 int t, n, m;
     7 int arr[N], res;
     8 
     9 int main()
    10 {
    11     scanf("%d", &t);
    12     while (t--)
    13     {
    14         res = 0;
    15         scanf("%d%d", &n, &m);
    16         for (int i = 1, b; i <= n; ++i) 
    17         {
    18             scanf("%d%d", arr + i, &b);
    19             if (b) ++res;
    20         }
    21         sort(arr + 1, arr + 1 + n);
    22         res = min(res, m);
    23         double ans = 0;
    24         for (int i = n; i >= 1; --i, --res)
    25             ans += res > 0 ? arr[i] * 1.0 / 2 : arr[i];
    26         printf("%.1f
    ", ans);
    27     }
    28     return 0;
    29 }
    View Code

    E    Trophies

    留坑。

    F    Palindrome

    留坑。

    G    Stones

    留坑。

    H    Travel

    思路:隔板法,一条边相当于划成两个区域。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3  
     4 #define ll long long
     5 #define N 100010
     6  
     7 const ll MOD = (ll)1e9 + 7;
     8  
     9 ll fac[N];
    10  
    11 void Init()
    12 {
    13     fac[0] = 1;
    14     for (int i = 1; i < N; ++i) fac[i] = fac[i - 1] * i % MOD;
    15 }
    16  
    17 ll qpow(ll base, ll n)
    18 {
    19     ll res = 1;
    20     while (n)
    21     {
    22         if (n & 1) res = res * base % MOD;
    23         base = base * base % MOD;
    24         n >>= 1;
    25     }
    26     return res;
    27 }
    28  
    29 ll C(ll n, ll m)
    30 {
    31     if (m > n) return 0;
    32     return fac[n] * qpow(fac[m] * fac[n - m] % MOD, MOD - 2) % MOD;
    33 }
    34  
    35 int t, n, m;
    36  
    37 int main()
    38 {
    39     Init();
    40     scanf("%d", &t);
    41     while (t--)
    42     {
    43         scanf("%d%d", &n, &m);
    44         for (int i = 1, a, b; i < n; ++i) scanf("%d%d", &a, &b);
    45         printf("%lld
    ", C(n - 1, m - 1) * fac[m] % MOD);
    46     }
    47     return 0;
    48 }
    View Code

    I    Metropolis

    思路:将所有大都会都放到最短路去跑多源最短路,记录每个点的最短路是由哪个点扩展而来

    显然,如果一个点源点i扩展到一个点j, 而点j又已经被点k扩展了,那么就没有必要扩展下去

    我们在枚举每一条边,更新答案

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 #define N 200010
      5 #define ll long long
      6 #define INFLL 0x3f3f3f3f3f3f3f3f
      7 
      8 struct Edge
      9 {
     10     int to, nx; ll w;
     11     Edge() {}
     12     Edge(int to, int nx, ll w) : to(to), nx(nx), w(w) {}
     13 }edge[N << 1];
     14 
     15 int n, m, p;
     16 int head[N], pos;
     17 int x[N], Belong[N];
     18 ll dis[N], ans[N];
     19 
     20 void addedge(int u, int v, ll w)
     21 {
     22     edge[++pos] = Edge(v, head[u], w); head[u] = pos; 
     23 }
     24 
     25 struct node
     26 {
     27     ll w; int u, v;
     28     node() {}
     29     node(int u, int v, ll w) : u(u), v(v), w(w) {}
     30     bool operator < (const node &r) const
     31     {
     32         return w > r.w;
     33     }
     34 };
     35 
     36 priority_queue <node> q;
     37 
     38 void Init()
     39 {
     40     memset(head, -1, sizeof head);
     41     pos = 0;
     42     while (!q.empty()) q.pop();
     43     memset(Belong, 0, sizeof Belong);
     44     memset(ans, 0x3f, sizeof ans);
     45 }
     46 
     47 void Dijkstra()
     48 {
     49     while (!q.empty())
     50     {
     51         node top = q.top(); q.pop();
     52         if (Belong[top.v]) continue;
     53         Belong[top.v] = top.u;
     54         dis[top.v] = top.w; 
     55         for (int it = head[top.v]; ~it; it = edge[it].nx)
     56         {
     57             int v = edge[it].to;
     58             q.emplace(top.u, v, top.w + edge[it].w);
     59         }
     60     }
     61 }
     62 
     63 void Run()
     64 {
     65     while (scanf("%d%d%d", &n, &m, &p) != EOF) 
     66     {
     67         Init();
     68         for (int i = 1; i <= p; ++i)
     69         {
     70             scanf("%d", x + i);
     71             q.emplace(x[i], x[i], 0);
     72         }
     73         for (int i = 1, u, v, w; i <= m; ++i)
     74         {
     75             scanf("%d%d%d", &u, &v, &w);
     76             addedge(u, v, w);
     77             addedge(v, u, w);
     78         }
     79         Dijkstra(); 
     80         for (int u = 1; u <= n; ++u)
     81         {
     82             for (int it = head[u]; ~it; it = edge[it].nx)
     83             {
     84                 int v = edge[it].to;
     85                 ll w = edge[it].w;
     86                 if (Belong[u] == Belong[v]) continue;
     87                 ans[Belong[u]] = min(ans[Belong[u]], dis[u] + dis[v] + w);
     88                 ans[Belong[v]] = min(ans[Belong[v]], dis[u] + dis[v] + w); 
     89             }
     90         }
     91         for (int i = 1; i <= p; ++i) printf("%lld%c", ans[x[i]], " 
    "[i == p]);
     92     }
     93 }
     94 
     95 int main()
     96 {
     97     #ifdef LOCAL
     98         freopen("Test.in", "r", stdin);
     99     #endif
    100 
    101     Run();
    102     return 0;
    103 }
    View Code

    J    Graph Coloring I

    思路:对于一张图,如果没有奇圈,那么肯定可以用两种颜色进行染色,那么肯定有解

    只要去找奇圈即可。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 
     4 #define N 300010
     5 
     6 int n, m;
     7 vector <int> G[N], ans;
     8 int deep[N], fa[N];
     9 bool flag;
    10 
    11 void DFS(int u)
    12 {
    13     if (flag) return; 
    14     for (auto v : G[u])
    15     {
    16         if (flag) return;
    17         if (v == fa[u]) continue;
    18         if (fa[v] != -1 && !flag)
    19         {
    20             if ((deep[u] - deep[v]) % 2 == 0)
    21             {
    22                 ans.push_back(u);
    23                 while (u != v)
    24                 {
    25                     u = fa[u];
    26                     ans.push_back(u);
    27                 }
    28                 flag = true;
    29                 return;
    30             }
    31         }
    32         else
    33         {
    34             fa[v] = u;
    35             deep[v] = deep[u] + 1;
    36             DFS(v);     
    37         }
    38     }
    39 }
    40 
    41 void Init()
    42 {
    43     for (int i = 1; i <= n; ++i) G[i].clear(); 
    44     ans.clear();
    45     memset(fa, -1, sizeof fa); 
    46     deep[1] = 0;     
    47     flag = false;
    48 }
    49 
    50 int main()
    51 {
    52     while (scanf("%d%d", &n, &m) != EOF)
    53     {
    54         Init();
    55         for (int i = 1, u, v; i <= m; ++i) 
    56         {
    57             scanf("%d%d", &u, &v);
    58             G[u].push_back(v);
    59             G[v].push_back(u);
    60         }
    61         DFS(1);
    62         if (flag)
    63         {
    64             printf("%d
    ", (int)ans.size());
    65             for (int i = 0, len = ans.size(); i < len; ++i) printf("%d%c", ans[i], " 
    "[i == len - 1]);
    66         }
    67         else
    68         {
    69             puts("0");
    70             for (int i = 1; i <= n; ++i) printf("%d%c", deep[i] & 1, " 
    "[i == n]);
    71         }
    72     }
    73     return 0;
    74 }
    View Code

    K    Graph Coloring II

    留坑。

  • 相关阅读:
    Python
    保护模式(九):挂物理页
    保护模式(八):MmIsAddressValid逆向(PAE)
    保护模式(七):2-9-9-12分页
    保护模式(六):10-10-12分页(二)
    保护模式(五):10-10-12分页(一)
    保护模式(四):任务段与任务门
    保护模式(三):中断门与陷阱门
    保护模式(二):调用门
    保护模式(一):段描述符与段选择子
  • 原文地址:https://www.cnblogs.com/Dup4/p/9740464.html
Copyright © 2011-2022 走看看