zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    URAL 1998 The old Padawan 二分
    URAL 1997 Those are not the droids you're looking for 二分图最大匹配
    URAL 1995 Illegal spices 贪心构造
    URAL 1993 This cheeseburger you don't need 模拟题
    URAL 1992 CVS
    URAL 1991 The battle near the swamp 水题
    Codeforces Beta Round #92 (Div. 1 Only) A. Prime Permutation 暴力
    Codeforces Beta Round #7 D. Palindrome Degree hash
    Codeforces Beta Round #7 C. Line Exgcd
    Codeforces Beta Round #7 B. Memory Manager 模拟题
  • 原文地址:https://www.cnblogs.com/NEIL74/p/3307725.html
Copyright © 2011-2022 走看看