10.17
看似在线,实际每个数字独立,可以每种数字拆出来考虑,转变为树上单点修改询问链。
维护差分,变为子树修改,单点询问,排好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 }
10.19
按时间分治带撤销并查集还是直接线段树暴力并查集吧。
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 */