• Codeforces Round #199 (Div. 2)


    A. Xenia and Divisors 水题

    B. Xenia and Spies 水题

    C. Cupboard and Balloons 水题

    D. Xenia and Dominoes

      DP:保存每一列的状态,一列一列的向后递推

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <algorithm>
      4 #include <cmath>
      5 #include <queue>
      6 #include <string>
      7 #include <map>
      8 #include <set>
      9 #include <iostream>
     10 #include <ctime>
     11 using namespace std;
     12 #define clr(a, b) memset(a, b, sizeof(a))
     13 #define sqr(x) ((x) * (x))
     14 #define ABS(x) max(x, -x)
     15 #define SB puts("sb");
     16 #define L(i) (i << 1)
     17 #define R(i) ((i << 1) | 1)
     18 typedef long long ll;
     19 const int INF = 0x3f3f3f3f;
     20 const int MOD = 1000000007;
     21 const int N = 10010;
     22 const int M = 1;
     23 
     24 char s[4][N];
     25 int n, dp[N][8];
     26 int sx, sy;
     27 
     28 void find() {
     29     for (int i = 1; i <= 3; ++i)
     30         for (int j = 1; j <= n; ++j) if (s[i][j] == 'O') {
     31             sx = i, sy = j;
     32             return;
     33         }
     34 }
     35 
     36 int num(int j) {
     37     int ret = 0;
     38     for (int i = 1; i <= 3; ++i) if (s[i][j] != '.') {
     39         ret += (1 << (3 - i));
     40     }
     41     return ret;
     42 }
     43 
     44 int cal_mode(int i, int k) {
     45     if (k == 0) return dp[i - 1][7];
     46     if (k == 1) return dp[i - 1][6];
     47     if (k == 2) return dp[i - 1][5];
     48     if (k == 3) return (dp[i - 1][7] + dp[i - 1][4]) % MOD;
     49     if (k == 4) return dp[i - 1][3];
     50     if (k == 5) return dp[i - 1][2];
     51     if (k == 6) return (dp[i - 1][7] + dp[i - 1][1]) % MOD;
     52     if (k == 7) return ((dp[i - 1][0] + dp[i - 1][3]) % MOD + dp[i - 1][6]) % MOD;
     53     return 0;
     54 }
     55 
     56 int cal() {
     57     clr(dp, 0);
     58     dp[0][7] = 1;
     59 
     60     for(int i = 1; i <= n; ++i)
     61     {
     62         int k = num(i);
     63         for (int j = k; j <= 7; ++j) if((j & k) == k)
     64             dp[i][j] = cal_mode(i, j - k);
     65     }
     66     return dp[n][7];
     67 }
     68 
     69 
     70 int main()
     71 {
     72     freopen("in", "r", stdin);
     73     freopen("out", "w", stdout);
     74     scanf("%d", &n);
     75     for (int i = 1; i <= 3; ++i) scanf("%s", s[i] + 1);
     76 
     77     find();
     78 
     79     if (sx == 2) {
     80         int ans = 0;
     81         bool f1 = 0, f2 = 0;
     82         if (sy >= 3) {
     83             if (s[2][sy - 2] == '.' && s[2][sy - 1] == '.') {
     84                 f1 = 1;
     85                 s[2][sy - 2] = s[2][sy - 1] = 'X';
     86                 ans += cal();
     87                 s[2][sy - 2] = s[2][sy - 1] = '.';
     88             }
     89         }
     90         if (sy + 2 <= n) {
     91             if (s[2][sy + 2] == '.' && s[2][sy + 1] == '.') {
     92                 f2 = 1;
     93                 s[2][sy + 2] = s[2][sy + 1] = 'X';
     94                 ans += cal();
     95                 s[2][sy + 2] = s[2][sy + 1] = '.';
     96             }
     97         }
     98         if (f1 && f2) {
     99             s[2][sy - 2] = s[2][sy - 1] = 'X';
    100             s[2][sy + 2] = s[2][sy + 1] = 'X';
    101             ans -= cal();
    102         }
    103         if (ans < 0) ans += MOD;
    104         printf("%d
    ", ans % MOD);
    105     }
    106     else
    107         printf("%d
    ", cal());
    108     return 0;
    109 }
    View Code

    E. Xenia and Tree

     

      此题的数据不给力啊,直接暴力的程序都过了。。。

      当要修改的节点数大于一定范围lim时,bfs一遍,修改所有节点的答案;否则先放到队列里,遇到查询直接用在线LCA求一下答案,至于范围lim,我觉得sqrt(n)比较合适,虽然没有直接暴力的程序快。。。

    code 1:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cmath>
      4 #include <algorithm>
      5 using namespace std;
      6 const int N = 100010;
      7 #define clr(a, b) memset(a, b, sizeof(a))
      8 
      9 int n, m, p[N][18], dis[N], d[N];
     10 int head[N], pre[N * 2], nxt[N * 2], e;
     11 int q[N], st, ed;
     12 bool inq[N];
     13 
     14 void init() {
     15     clr(head, -1);
     16     clr(p, -1);
     17     e = 0;
     18 }
     19 
     20 void addedge(int u, int v) {
     21     pre[e] = v, nxt[e] = head[u], head[u] = e++;
     22     pre[e] = u, nxt[e] = head[v], head[v] = e++;
     23 }
     24 
     25 void dfs(int u, int f) {
     26     p[u][0] = f;
     27     if (~f) d[u] = d[f] + 1;
     28     for (int i = 0; ~p[u][i]; ++i)
     29         p[u][i + 1] = p[ p[u][i] ][i];
     30     for (int i = head[u]; ~i; i = nxt[i]) {
     31         int v = pre[i];
     32         if (v == f) continue;
     33         dfs(v, u);
     34     }
     35 }
     36 
     37 int OnlineLCA(int u, int v) {
     38     if (d[u] < d[v]) swap(u, v);
     39     int del = d[u] - d[v];
     40     for (int i = 0; del; ++i) if (del & (1 << i)) {
     41         del -= (1 << i);
     42         u = p[u][i];
     43     }
     44     int lim = ceil(log(d[u]) / log(2));
     45     if (u != v) {
     46         for (int i = lim; i >= 0; --i) if(p[u][i] != p[v][i]) {
     47             u = p[u][i];
     48             v = p[v][i];
     49         }
     50         u = p[u][0];
     51     }
     52     return u;
     53 }
     54 
     55 void bfs() {
     56     clr(inq, 0);
     57     while (st <= ed) {
     58         int u = q[st++];
     59         for (int i = head[u]; ~i; i = nxt[i]) {
     60             int v = pre[i];
     61             if (dis[v] > dis[u] + 1) {
     62                 dis[v] = dis[u] + 1;
     63                 if (!inq[v]) {
     64                     q[++ed] = v;
     65                     inq[v] = 1;
     66                 }
     67             }
     68         }
     69     }
     70 }
     71 
     72 int main() {
     73     freopen("in", "r", stdin);
     74     freopen("out", "w", stdout);
     75     init();
     76     scanf("%d%d", &n, &m);
     77     int x, y;
     78     for (int i = 1; i < n; ++i) {
     79         scanf("%d%d", &x, &y);
     80         addedge(x, y);
     81     }
     82     dfs(1, -1);
     83 
     84     memcpy(dis, d, sizeof(d));
     85     int block = (int)sqrt(n + 0.5);
     86 
     87     st = 0, ed = -1;
     88 
     89     while (m--) {
     90         scanf("%d%d", &x, &y);
     91         if (x == 1) {
     92             q[++ed] = y;
     93             dis[y] = 0;
     94         }
     95         else {
     96             if (ed - st > block) {
     97                 bfs();
     98                 printf("%d
    ", dis[y]);
     99                 st = 0, ed = -1;
    100             }
    101             else {
    102                 int ans = dis[y];
    103                 for (int i = st; i <= ed; ++i) {
    104                     int anc = OnlineLCA(y, q[i]);
    105                     ans = min(ans, d[y] + d[ q[i] ] - 2 * d[anc]);
    106                 }
    107                 printf("%d
    ", ans);
    108             }
    109         }
    110     }
    111     return 0;
    112 }
    View Code

    code 2:

      1 #include <cstdio>
      2 #include <cstring>
      3 #include <cmath>
      4 #include <algorithm>
      5 using namespace std;
      6 const int N = 200010;
      7 #define clr(a, b) memset(a, b, sizeof(a))
      8 
      9 int n, m, dis[N], d[N], dfn[N], cnt, euler[N];
     10 int head[N], pre[N], nxt[N], e;
     11 int q[N], st, ed;
     12 bool inq[N];
     13 
     14 void init() {
     15     clr(head, -1);
     16     e = 0;
     17     cnt = 0;
     18 }
     19 
     20 void addedge(int u, int v) {
     21     pre[e] = v, nxt[e] = head[u], head[u] = e++;
     22     pre[e] = u, nxt[e] = head[v], head[v] = e++;
     23 }
     24 
     25 struct RMQ {
     26     int LOG[N], d[N][20];
     27     RMQ() {
     28         LOG[0] = -1;
     29         for (int i = 1; i < N; ++i) LOG[i] = LOG[i >> 1] + 1;
     30     }
     31     void init(int *a, int *b, int n) {
     32         for (int i = 1; i <= n; ++i) d[i][0] = b[i];
     33         for (int j = 1; j <= LOG[n]; ++j)
     34             for (int i = 1; j <= LOG[n - i] + 1; ++i) {
     35                 if (a[d[i][j-1]] < a[d[i + (1 << (j-1))][j-1]])
     36                     d[i][j] = d[i][j-1];
     37                 else
     38                     d[i][j] = d[i+(1<<(j-1))][j-1];
     39             }
     40     }
     41     int query(int *a, int l, int r) {
     42         int k = LOG[r - l + 1];
     43         if (a[d[l][k]] < a[d[r- (1 << k) + 1][k]])
     44             return d[l][k];
     45         else
     46             return d[r- (1 << k) + 1][k];
     47     }
     48 };
     49 RMQ rq;
     50 
     51 void dfs(int u, int f) {
     52     euler[++cnt] = u;
     53     dfn[u] = cnt;
     54     d[u] = d[f] + 1;
     55     for (int i = head[u]; ~i; i = nxt[i]) {
     56         int v = pre[i];
     57         if (v == f) continue;
     58         dfs(v, u);
     59         euler[++cnt] = u;
     60     }
     61 }
     62 
     63 void bfs() {
     64     clr(inq, 0);
     65     while (st <= ed) {
     66         int u = q[st++];
     67         for (int i = head[u]; ~i; i = nxt[i]) {
     68             int v = pre[i];
     69             if (dis[v] > dis[u] + 1) {
     70                 dis[v] = dis[u] + 1;
     71                 if (!inq[v]) {
     72                     q[++ed] = v;
     73                     inq[v] = 1;
     74                 }
     75             }
     76         }
     77     }
     78 }
     79 
     80 int OnlineLCA(int u, int v) {
     81     if (dfn[u] > dfn[v]) swap(u, v);
     82     return rq.query(d, dfn[u], dfn[v]);
     83 };
     84 
     85 int main() {
     86     freopen("in", "r", stdin);
     87     freopen("out", "w", stdout);
     88     init();
     89     scanf("%d%d", &n, &m);
     90     int x, y;
     91     for (int i = 1; i < n; ++i) {
     92         scanf("%d%d", &x, &y);
     93         addedge(x, y);
     94     }
     95 
     96     d[0] = -1;
     97     dfs(1, 0);
     98 
     99     rq.init(d, euler, 2 * n - 1);
    100 
    101     memcpy(dis, d, sizeof(d));
    102     int block = (int)sqrt(n + 0.5);
    103 
    104     st = 0, ed = -1;
    105     while (m--) {
    106         scanf("%d%d", &x, &y);
    107         if (x == 1) {
    108             q[++ed] = y;
    109             dis[y] = 0;
    110         }
    111         else {
    112             if (ed - st > block) {
    113                 bfs();
    114                 printf("%d
    ", dis[y]);
    115                 st = 0, ed = -1;
    116             }
    117             else {
    118                 int ans = dis[y];
    119                 for (int i = st; i <= ed; ++i) {
    120                     int anc = OnlineLCA(y, q[i]);
    121                     ans = min(ans, d[y] + d[q[i]] - 2 * d[anc]);
    122                 }
    123                 printf("%d
    ", ans);
    124             }
    125         }
    126     }
    127     return 0;
    128 }
    View Code
  • 相关阅读:
    leetcode-mid-array-5. Longest Palindromic Substring
    leetcode-mid-array-334 Increasing Triplet Subsequence-NO
    leetcode-mid-array-3 Longest Substring Without Repeating Characters
    leetcode-mid-array-49 Group Anagrams
    leetcode-mid-array-73 set matrix zeros
    leetcode-mid-array-31 three sum-NO
    ANOVA-方差分析和单尾方差分析
    MTLD -词汇复杂度的指标
    shell脚本-2
    from __future__ import
  • 原文地址:https://www.cnblogs.com/NEIL74/p/3307725.html
Copyright © 2020-2023  润新知