zoukankan      html  css  js  c++  java
  • 离线强化训练

    10.17

    HYSBZ - 4999

    看似在线,实际每个数字独立,可以每种数字拆出来考虑,转变为树上单点修改询问链。

    维护差分,变为子树修改,单点询问,排好dfs序后用线段树维护。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <vector>
      4 #include <algorithm>
      5 #include <set>
      6 using namespace std;
      7 const int maxn = 1e5 + 10;
      8 int a[maxn], c[maxn];
      9 vector<int> b, g[maxn];
     10 int op[200005], I[200005], J[200005], X[200005], ans[200005];
     11 
     12 typedef pair<int, int> pii;
     13 vector<pii> q[300005];
     14 set<int> S;
     15 set<int> :: iterator it;
     16 
     17 // LCA
     18 int dfs_clock = 0;
     19 int dep[maxn], l[maxn], r[maxn];
     20 int anc[maxn][33];
     21 void dfs(int x, int fa)
     22 {
     23     l[x] = r[x] = ++dfs_clock;
     24     for(int i = 0; i < g[x].size(); i++)
     25     {
     26         int to = g[x][i];
     27         if(to == fa) continue;
     28         dep[to] = dep[x] + 1;
     29         anc[to][0] = x;
     30         dfs(to, x);
     31         r[x] = r[to];
     32     }
     33 }
     34 void LCA_init(int n)
     35 {
     36     for(int j = 1; (1 << j) < n; j++)
     37         for(int i = 1; i <= n; i++) if(anc[i][j-1])
     38             anc[i][j] = anc[anc[i][j-1]][j-1];
     39 }
     40 int LCA(int u, int v)
     41 {
     42     int log;
     43     if(dep[u] < dep[v]) swap(u, v);
     44     for(log = 0; (1 << log) < dep[u]; log++);
     45     for(int i = log; i >= 0; i--)
     46         if(dep[u] - (1<<i) >= dep[v]) u = anc[u][i];
     47     if(u == v) return u;
     48     for(int i = log; i >= 0; i--)
     49         if(anc[u][i] && anc[u][i] != anc[v][i])
     50             u = anc[u][i], v = anc[v][i];
     51     return anc[u][0];
     52 }
     53 
     54 // segment_tree
     55 int tag[maxn<<2];
     56 void modify(int p, int tl, int tr, int l, int r, int x)
     57 {
     58     if(tr < l || r < tl) return;
     59     if(l <= tl && tr <= r)
     60     {
     61         tag[p] += x;
     62         return;
     63     }
     64     int mid = (tl + tr) >> 1;
     65     modify(p<<1, tl, mid, l, r, x);
     66     modify(p<<1|1, mid+1, tr, l, r, x);
     67 }
     68 int query(int p, int tl, int tr, int x)
     69 {
     70     if(x == 0) return 0;
     71     int ret = tag[p];
     72     if(tl == tr) return ret;
     73     int mid = (tl + tr) >> 1;
     74     if(x <= mid) ret += query(p<<1, tl, mid, x);
     75     else ret += query(p<<1|1, mid+1, tr, x);
     76     return ret;
     77 }
     78 
     79 int main(void)
     80 {
     81     int N, Q;
     82     scanf("%d %d", &N, &Q);
     83     for(int i = 1; i <= N; i++) scanf("%d", a + i), b.push_back(a[i]);
     84     for(int i = 1; i < N; i++)
     85     {
     86         int u, v;
     87         scanf("%d %d", &u, &v);
     88         g[u].push_back(v);
     89         g[v].push_back(u);
     90     }
     91     for(int i = 1; i <= Q; i++)
     92     {
     93         char s[11];
     94         scanf("%s", s);
     95         if(s[0] == 'C')
     96         {
     97             op[i] = 1;
     98             scanf("%d %d", I + i, X + i);
     99         }
    100         else
    101         {
    102             op[i] = 2;
    103             scanf("%d %d %d", I + i, J + i, X + i);
    104         }
    105         b.push_back(X[i]);
    106     }
    107     sort(b.begin(), b.end());
    108     b.erase(unique(b.begin(), b.end()), b.end());
    109     for(int i = 1; i <= N; i++) a[i] = lower_bound(b.begin(), b.end(), a[i]) - b.begin() + 1;
    110     for(int i = 1; i <= Q; i++) X[i] = lower_bound(b.begin(), b.end(), X[i]) - b.begin() + 1;
    111     for(int i = 1; i <= N; i++) c[i] = a[i], q[c[i]].push_back(pii(1, i));
    112     for(int i = 1; i <= Q; i++)
    113     {
    114         if(op[i] == 1)
    115         {
    116             q[c[I[i]]].push_back(pii(-1, I[i]));
    117             q[X[i]].push_back(pii(1, I[i]));
    118             c[I[i]] = X[i];
    119         }
    120         else q[X[i]].push_back(pii(0, i));
    121     }
    122     dfs(1, 0);
    123     LCA_init(N);
    124     for(int i = 1; i <= b.size(); i++)
    125     {
    126         for(int j = 0; j < q[i].size(); j++)
    127         {
    128             int x = q[i][j].first, y = q[i][j].second;
    129             if(x == 1) modify(1, 1, N, l[y], r[y], 1), S.insert(y);
    130             if(x == -1) modify(1, 1, N, l[y], r[y], -1), S.erase(y);
    131             if(x == 0) ans[y] = query(1, 1, N, l[I[y]]) + query(1, 1, N, l[J[y]]) - query(1, 1, N, l[LCA(I[y], J[y])]) - query(1, 1, N, l[anc[LCA(I[y], J[y])][0]]);
    132         }
    133         for(it = S.begin(); it != S.end(); it++) modify(1, 1, N, l[*it], r[*it], -1);
    134         S.clear();
    135     }
    136     for(int i = 1; i <= Q; i++)
    137         if(op[i] == 2) printf("%d
    ", ans[i]);
    138     return 0;
    139 }
    Aguin

    10.19

    HYSBZ - 1453

    按时间分治带撤销并查集还是直接线段树暴力并查集吧。

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <cstring>
      5 using namespace std;
      6 const int maxn = 205;
      7 int G[maxn][maxn];
      8 int x[11111], y[11111];
      9 int n, m;
     10 
     11 int fa[808], tmp[808];
     12 int Find(int x)
     13 {
     14     return fa[x] == x ? x : fa[x] = Find(fa[x]);
     15 }
     16 inline void Union(int x, int y)
     17 {
     18     x = Find(x), y = Find(y);
     19     if(x < y) swap(x, y);
     20     fa[x] = y;
     21 }
     22 int L[maxn<<2][maxn], R[maxn<<2][maxn], sum[maxn<<2][2];
     23 inline void gather(int p, int tl, int tr)
     24 {
     25     sum[p][0] = sum[p<<1][0] + sum[p<<1|1][0];
     26     sum[p][1] = sum[p<<1][1] + sum[p<<1|1][1];
     27     for(int i = 1; i <= n; i++)
     28     {
     29         fa[i] = L[p<<1][i];
     30         fa[i+n] = R[p<<1][i];
     31         fa[i+n+n] = n + n + L[p<<1|1][i];
     32         fa[i+n+n+n] = n + n + R[p<<1|1][i];
     33         tmp[i] = tmp[i+n] = tmp[i+n+n] = tmp[i+n+n+n] = 0;
     34     }
     35     int mid = (tl + tr) >> 1;
     36     for(int i = 1; i <= n; i++)
     37         if(G[mid][n-i+1] == G[mid+1][n-i+1] && Find(i+n) != Find(i+n+n))
     38             Union(i + n, i + n + n), sum[p][G[mid][n-i+1]]--;
     39     for(int i = 1; i <= n; i++)
     40         L[p][i] = Find(i), R[p][i] = Find(i+n+n+n);
     41     for(int i = 1; i <= n; i++)
     42     {
     43         if(R[p][i] <= n) continue;
     44         if(tmp[R[p][i]]) R[p][i] = tmp[R[p][i]];
     45         else tmp[R[p][i]] = n + i, R[p][i] = n + i;
     46     }
     47 }
     48 void build(int p, int tl, int tr)
     49 {
     50     if(tl == tr)
     51     {
     52         sum[p][0] = sum[p][1] = 0;
     53         for(int i = 1; i <= n; i++)
     54         {
     55             if(i != 1 && G[tl][n-i+1] == G[tl][n-i+2]) L[p][i] = R[p][i] = L[p][i-1];
     56             else L[p][i] = R[p][i] = i, sum[p][G[tl][n-i+1]]++;
     57         }
     58         return;
     59     }
     60     int mid = (tl + tr) >> 1;
     61     build(p<<1, tl, mid);
     62     build(p<<1|1, mid+1, tr);
     63     gather(p, tl, tr);
     64 }
     65 void modify(int p, int tl, int tr, int x)
     66 {
     67     if(tl == tr)
     68     {
     69         sum[p][0] = sum[p][1] = 0;
     70         for(int i = 1; i <= n; i++)
     71         {
     72             if(i != 1 && G[tl][n-i+1] == G[tl][n-i+2]) L[p][i] = R[p][i] = L[p][i-1];
     73             else L[p][i] = R[p][i] = i, sum[p][G[tl][n-i+1]]++;
     74         }
     75         return;
     76     }
     77     int mid = (tl + tr) >> 1;
     78     if(x <= mid) modify(p<<1, tl, mid, x);
     79     else modify(p<<1|1, mid+1, tr, x);
     80     gather(p, tl, tr);
     81 }
     82 
     83 int main(void)
     84 {
     85     scanf("%d", &n);
     86     for(int i = 1; i <= n; i++)
     87         for(int j = 1; j <= n; j++)
     88             scanf("%d", &G[i][j]);
     89     build(1, 1, n);
     90     scanf("%d", &m);
     91     for(int i = 1; i <= m; i++)
     92     {
     93         scanf("%d %d", x + i, y + i);
     94         G[x[i]][y[i]] ^= 1;
     95         modify(1, 1, n, x[i]);
     96         printf("%d %d
    ", sum[1][1], sum[1][0]);
     97     }
     98     return 0;
     99 }
    100 /*
    101 5
    102 0 1 0 0 0
    103 0 1 1 1 0
    104 1 0 0 0 1
    105 0 0 1 0 0
    106 1 0 0 0 0
    107 2
    108 3 2
    109 2 3
    110 */
    Aguin
  • 相关阅读:
    Python解释器相关知识
    简单了解下Flask
    Scoket编程
    __file__的作用
    jquery编写可折叠列表
    浑浑噩噩的一天
    js实现杨辉三角
    js闭包
    python读取word表格
    HTMLTestRunner报告
  • 原文地址:https://www.cnblogs.com/Aguin/p/7684463.html
Copyright © 2011-2022 走看看