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
  • 相关阅读:
    Vsftpd 3.0.2 正式版发布
    Putdb WebBuilder 6.5 正式版本发布
    SoaBox 1.1.6 GA 发布,SOA 模拟环境
    pynag 0.4.6 发布,Nagios配置和插件管理
    Percona Playback 0.4,MySQL 负荷回放工具
    xombrero 1.3.1 发布,微型 Web 浏览器
    Hypertable 0.9.6.4 发布,分布式数据库
    libmemcached 1.0.11 发布
    CryptoHeaven 3.7 发布,安全邮件解决方案
    Android Activity生命周期
  • 原文地址:https://www.cnblogs.com/Aguin/p/7684463.html
Copyright © 2011-2022 走看看