zoukankan      html  css  js  c++  java
  • 2018.10.04模拟总结

    今天的模拟也太毒瘤了……

     

    T1 permutation

      期望得分:20

      实际得分:20  

      我刚开始是这么想的:T1嘛,应该不会太难,想想正解吧。本来想求出所有不合法的情况,然后用n!减一下。于是用dp,但发现这玩意是有后效性的,硬推了将近一个点儿,最终还是放弃了。只能20分全排列暴力了……

      正解完全没看懂,居然成了什么二分图的补图,然后还用什么卷积……弃疗了

    20分的

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cctype>
     8 #include<vector>
     9 #include<stack>
    10 #include<queue>
    11 using namespace std;
    12 #define enter puts("") 
    13 #define space putchar(' ')
    14 #define Mem(a, x) memset(a, x, sizeof(a))
    15 #define rg register
    16 typedef long long ll;
    17 typedef double db;
    18 const int INF = 0x3f3f3f3f;
    19 const db eps = 1e-8;
    20 const int maxn = 12;
    21 const ll mod = 998244353;
    22 inline ll read()
    23 {
    24     ll ans = 0;
    25     char ch = getchar(), last = ' ';
    26     while(!isdigit(ch)) {last = ch; ch = getchar();}
    27     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
    28     if(last == '-') ans = -ans;
    29     return ans;
    30 }
    31 inline void write(ll x)
    32 {
    33     if(x < 0) x = -x, putchar('-');
    34     if(x >= 10) write(x / 10);
    35     putchar(x % 10 + '0');
    36 }
    37 
    38 int n, k, a[maxn];
    39 ll ans = 0;
    40 
    41 ll fac[maxn * 10000];
    42 void work0()
    43 {
    44     fac[1] = 1;
    45     for(int i = 2; i <= n; ++i) fac[i] = fac[i - 1] * i % mod;
    46     write((fac[n] - fac[n - 1]) % mod); enter;
    47 }
    48 
    49 int main()
    50 {
    51     freopen("permutation.in", "r", stdin);
    52     freopen("permutation.out", "w", stdout);
    53     n = read(); k = read();
    54     if(n > 10) {work0(); return 0;}
    55     for(rg int i = 1; i <= n; ++i) a[i] = i;
    56     do
    57     {
    58         bool flg = 1;
    59         for(rg int i = 1; i <= n; ++i) if(abs(a[i] - i) == k) {flg = 0; break;}
    60         if(flg) ans++;
    61     }while(next_permutation(a + 1, a + n + 1));
    62     write(ans % mod); enter;
    63     return 0;
    64 }
    View Code

    T2 tree

      期望得分:60

      实际得分:55

      60分多好写啊!枚举每一个不在树上的边,删去他然后跑tarjan求桥。丢了5分是因为不在树上的边和树上的边构成了重边,tarjan的时候还要单独判断一下这条边是否是新加的。

    代码

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cmath>
     4 #include<algorithm>
     5 #include<cstring>
     6 #include<cstdlib>
     7 #include<cctype>
     8 #include<vector>
     9 #include<stack>
    10 #include<queue>
    11 using namespace std;
    12 #define enter puts("") 
    13 #define space putchar(' ')
    14 #define Mem(a, x) memset(a, x, sizeof(a))
    15 #define rg register
    16 typedef long long ll;
    17 typedef double db;
    18 const int INF = 0x3f3f3f3f;
    19 const db eps = 1e-8;
    20 const int maxn = 3e5 + 5;
    21 inline ll read()
    22 {
    23     ll ans = 0;
    24     char ch = getchar(), last = ' ';
    25     while(!isdigit(ch)) {last = ch; ch = getchar();}
    26     while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();}
    27     if(last == '-') ans = -ans;
    28     return ans;
    29 }
    30 inline void write(ll x)
    31 {
    32     if(x < 0) x = -x, putchar('-');
    33     if(x >= 10) write(x / 10);
    34     putchar(x % 10 + '0');
    35 }
    36 
    37 int n, m;
    38 #define pr pair<int, int>
    39 #define mp make_pair
    40 vector<pr> v[maxn];
    41 
    42 ll ans = 0;
    43 int dfn[maxn], low[maxn], cnt;
    44 void tarjan(const int& now, const int& fa, const int& flg)
    45 {
    46     dfn[now] = low[now] = ++cnt;
    47     for(int i = 0; i < (int)v[now].size(); ++i)
    48     {
    49         if(v[now][i].second == flg) continue;
    50         int to = v[now][i].first;
    51         if(!dfn[to])
    52         {
    53             tarjan(to, now, flg);
    54             low[now] = min(low[now], low[to]);
    55             if(low[to] > dfn[now]) ans++;
    56         }
    57         else if(to != fa || v[now][i].second) low[now] = min(low[now], dfn[to]);
    58     }
    59 }
    60 inline void init()
    61 {
    62     for(int i = 1; i <= n; ++i) dfn[i] = low[i] = 0;
    63     cnt = 0;
    64 }
    65 
    66 int main()
    67 {
    68     freopen("tree.in", "r", stdin);
    69     freopen("tree.out", "w", stdout);
    70     n = read(); m = read();
    71     for(int i = 1; i < n; ++i)
    72     {
    73         int x = read(), y = read();
    74         v[x].push_back(mp(y, 0)); v[y].push_back(mp(x, 0));
    75     }
    76     for(int i = 1; i <= m; ++i)
    77     {
    78         int x = read(), y = read();
    79         v[x].push_back(mp(y, i)); v[y].push_back(mp(x, i));
    80     }
    81     for(int i = 1; i <= m; ++i)
    82     {
    83         init();
    84         for(int j = 1; j <= n; ++j) if(!dfn[j]) tarjan(j, 0, i);
    85     }
    86     write(ans); enter;
    87     return 0;
    88 }
    View Code

      正解现在看起来也不难:对于新加入的一条边(x, y),对于原来树上的路径x -> y的所有边而言,必须要割掉这条新的边和自己,才能使整棵树不连通;而如果又有一条边(x, y),则这些路径上的边怎么割都割不掉了。所以总结一下:新加入一条边(x, y)相当于树上路径加1,最后判断这条边的值:如果是1,对答案的贡献就是1,;如果是0,贡献就是m;否则是0.

      链上修改可以用树剖,更优的解法是树上差分。时间复杂度取决于lca复杂度。

    85分代码(不知为啥有三个点RE了,调了小半个下午没调出来)

      1 #include<cstdio>
      2 #include<iostream>
      3 #include<cmath>
      4 #include<algorithm>
      5 #include<cstring>
      6 #include<cstdlib>
      7 #include<cctype>
      8 #include<vector>
      9 #include<stack>
     10 #include<queue>
     11 using namespace std;
     12 #define enter puts("")
     13 #define space putchar(' ')
     14 #define Mem(a, x) memset(a, x, sizeof(a))
     15 #define rg register
     16 typedef long long ll;
     17 typedef double db;
     18 const int INF = 0x3f3f3f3f;
     19 const db eps = 1e-8;
     20 const int maxn = 3e5 + 5;
     21 inline ll read()
     22 {
     23     ll ans = 0;
     24     char ch = getchar(), last = ' ';
     25     while(!isdigit(ch)) last = ch, ch = getchar();
     26     while(isdigit(ch)) ans = ans * 10 + ch - '0', ch = getchar();
     27     if(last == '-') ans = -ans;
     28     return ans;
     29 }
     30 inline void write(ll x)
     31 {
     32     if(x < 0) x = -x, putchar('-');
     33     if(x >= 10) write(x / 10);
     34     putchar(x % 10 + '0');
     35 }
     36 
     37 void MYFILE()
     38 {
     39 #ifndef mrclr
     40     freopen("tree.in", "r", stdin);
     41     freopen("tree.out", "w", stdout);
     42 #endif
     43 }
     44 
     45 int n, m;
     46 struct Edge
     47 {
     48     int nxt, to;
     49 }e[maxn << 2];
     50 int head[maxn], ecnt = 0;
     51 void add(int x, int y)
     52 {
     53     e[++ecnt].to = y;
     54     e[ecnt].nxt = head[x];
     55     head[x] = ecnt;
     56 }
     57 
     58 int dep[maxn], dp[maxn][28];
     59 void dfs(int now, int fa)
     60 {
     61     for(int i = 1; i <= 25; ++i)
     62         dp[now][i] = dp[dp[now][i - 1]][i - 1];
     63     for(int i = head[now]; i; i = e[i].nxt)
     64     {
     65         if(e[i].to != fa)
     66         {
     67             dep[e[i].to] = dep[now] + 1;
     68             dp[e[i].to][0] = now;
     69             dfs(e[i].to, now);
     70         }
     71     }
     72 }
     73 int lca(int x, int y)
     74 {
     75     if(dep[x] < dep[y]) swap(x, y);
     76     for(int i = 25; i >= 0; --i)
     77         if(dep[dp[x][i]] >= dep[y]) x = dp[x][i];
     78     if(x == y) return x;
     79     for(int i = 25; i >= 0; --i)
     80         if(dp[x][i] != dp[y][i]) x = dp[x][i], y = dp[y][i];
     81     return dp[x][0];
     82 }
     83 
     84 int dif[maxn];
     85 void dfs2(int now, int fa)
     86 {
     87     for(int i = head[now]; i; i = e[i].nxt)
     88     {
     89         if(e[i].to != fa)
     90         {
     91             dfs2(e[i].to, now);
     92             dif[now] += dif[e[i].to];
     93         }
     94     }
     95 }
     96 
     97 int main()
     98 {
     99     MYFILE();
    100     n = read();
    101     m = read();
    102     for(int i = 1; i < n; ++i)
    103     {
    104         int x = read(), y = read();
    105         if(x == y) continue;
    106         add(x, y); add(y, x);
    107     }
    108     dfs(1, 0);
    109     for(int i = 1; i <= m; ++i)
    110     {
    111         int x = read(), y = read();
    112         dif[x]++; dif[y]++; 
    113         dif[lca(x, y)] -= 2;
    114     }
    115     dfs2(1, 0);
    116     ll ans = 0;
    117     for(rg int i = 1; i <= n; ++i)
    118     {
    119         ans += (dif[i] == 1);
    120         ans += (dif[i] == 0) * m;
    121     }
    122     write(ans - m); enter;
    123     return 0;
    124 }
    View Code

    T3 polynomial

      期望得分:0

      实际得分:0

      模拟能放到T3,那自然不可做。

      30分手推还是gg了。题解看不懂。

    明天我觉得应该能考数据结构吧。

  • 相关阅读:
    No.20 selenium学习之路之文件读写
    No.19 selenium学习之路之os模块
    No.18 selenium学习之路之批量执行测试用例
    python进阶学习之高阶函数
    python进阶学习之匿名函数lambda
    No.17 selenium学习之路之判断与等待
    Educational Codeforces Round 83 (Rated for Div. 2)【ABCDEF】(题解)
    Codeforces Round #626 (Div. 2, based on Moscow Open Olympiad in Informatics)【ABCDE】(题解)
    牛客练习赛58【ABCDEF】(题解)
    CodeCraft-20 (Div. 2)【ABCDE】(题解)
  • 原文地址:https://www.cnblogs.com/mrclr/p/9742380.html
Copyright © 2011-2022 走看看