bzoj 4817: [Sdoi2017]树点涂色
2017-04-16 19:51
399 查看
lct。
第一个操作就是access的过程中,把当前点的prefer child子树(也就是要断掉的重链那边,所有的点答案加1),然后就是新的prefer child的子树里面所有节点答案减1,因为lct是splay维护的,所以就要沿着splay往左走,找到深度最小的节点,用dfs序更新
第二个操作就是查询x,y到根的答案,再减去2倍的lca,加上1(lca被减了2次
第三种操作就是查询子树的最大值。
第一个操作就是access的过程中,把当前点的prefer child子树(也就是要断掉的重链那边,所有的点答案加1),然后就是新的prefer child的子树里面所有节点答案减1,因为lct是splay维护的,所以就要沿着splay往左走,找到深度最小的节点,用dfs序更新
第二个操作就是查询x,y到根的答案,再减去2倍的lca,加上1(lca被减了2次
第三种操作就是查询子树的最大值。
#include <bits/stdc++.h> using namespace std; #define LL long long #define ULL unsigned long long #define pii pair<int, int> #define MP make_pair #define ls i << 1 #define rs ls | 1 #define md (ll + rr >> 1) #define lson ll, md, ls #define rson md + 1, rr, rs #define mod 1000000007 #define inf 0x3f3f3f3f #define Pi acos(-1.0) #define eps 1e-12 #define N 200020 #define M 400020 int fst , vv[M], nxt[M], e; int L , R , lab , dc; int dep , fa [22]; int ch [2], pre ; int n, m; int mx[N<<2], down[N<<2]; void init(){ for(int i = 0; i <= n; ++i) fst[i] = -1; e = 0; } void add(int u, int v){ vv[e] = v, nxt[e] = fst[u], fst[u] = e++; } void update(int l, int r, int v, int ll, int rr, int i){ // printf("%d %d %d %d\n", l, r, ll, rr); if(l == ll && r == rr){ down[i] += v; mx[i] += v; return ; } if(r <= md) update(l, r, v, lson); else if(l > md) update(l, r, v, rson); else update(l, md, v, lson), update(md + 1, r, v, rson); mx[i] = max(mx[ls], mx[rs]) + down[i]; } int query(int l, int r, int ll, int rr, int i){ if(l == ll && r == rr) return mx[i]; int ret = 0; if(r <= md) ret = query(l, r, lson); else if(l > md) ret = query(l, r, rson); else ret = max(query(l, md, lson), query(md + 1, r, rson)); return ret + down[i]; } void dfs(int u, int p, int d){ fa[u][0] = p, dep[u] = d; L[u] = ++dc, lab[dc] = u; pre[u] = p; ch[u][0] = ch[u][1] = 0; for(int i = fst[u]; ~i; i = nxt[i]){ int v = vv[i]; if(v == p) continue; dfs(v, u, d + 1); } update(L[u], L[u], d, 1, n, 1); R[u] = dc; } void lca_init(){ for(int k = 0; k < 21; ++k) for(int i = 1; i <= n; ++i){ fa[i][k+1] = fa[fa[i][k]][k]; } } int lca(int u, int v){ if(dep[u] > dep[v]) swap(u, v); for(int i = 21; i >= 0; --i){ if((dep[v] - dep[u]) >> i & 1) v = fa[v][i]; } if(u == v) return u; for(int i = 21; i >= 0; --i) if(fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i]; return fa[u][0]; } bool rt(int x){ return pre[x] == 0 || ch[pre[x]][0] != x && ch[pre[x]][1] != x; } void rot(int x){ int y = pre[x], d = ch[y][1] == x; if(!rt(y)) ch[pre[y]][ch[pre[y]][1]==y] = x; ch[y][d] = ch[x][!d]; pre[ch[x][!d]] = y; ch[x][!d] = y; pre[x] = pre[y]; pre[y] = x; } void splay(int x){ while(!rt(x)){ int f = pre[x], ff = pre[f]; if(rt(f)) rot(x); else if((ch[ff][1] == f) == (ch[f][1] == x)) rot(f), rot(x); else rot(x), rot(x); } } int find(int x){ while(ch[x][0]) x = ch[x][0]; return x; } void access(int x){ for(int y = 0; x; y = x, x = pre[x]){ splay(x); if(ch[x][1]){ int p = find(ch[x][1]); //printf("%d\n", p); int l = L[p], r = R[p]; update(l, r, 1, 1, n, 1); } if(y){ int p = find(y); // printf("%d\n", p); int l = L[p], r = R[p]; update(l, r, -1, 1, n, 1); } ch[x][1] = y; } } int main(){ scanf("%d%d", &n, &m); init(); for(int i = 1; i < n; ++i){ int u, v; scanf("%d%d", &u, &v); add(u, v); add(v, u); } dfs(1, 0, 1); lca_init(); while(m--){ int op, x, y; scanf("%d", &op); if(op == 1){ scanf("%d", &x); access(x); } else if(op == 2){ scanf("%d%d", &x, &y); int ans = 0, l, r, p = lca(x, y); // printf("op2 %d %d %d\n", x, y, p); l = r = L[x]; ans += query(l, r, 1, n, 1); l = r = L[y]; ans += query(l, r, 1, n, 1); l = r = L[p]; ans -= query(l, r, 1, n, 1) * 2; printf("%d\n", ans + 1); } else{ scanf("%d", &x); int l = L[x], r = R[x]; // printf("query %d %d %d\n", x, l, r); printf("%d\n", query(l, r, 1, n, 1)); } } return 0; }
相关文章推荐
- [LCT] BZOJ4817.[Sdoi2017]树点涂色
- [BZOJ]4817: [Sdoi2017]树点涂色
- BZOJ 4817: [Sdoi2017]树点涂色
- BZOJ 4817: [Sdoi2017]树点涂色(LCT+树剖+线段树)
- bzoj 4817: [Sdoi2017]树点涂色 LCT+树链剖分+线段树
- bzoj 4817: [Sdoi2017]树点涂色【树链剖分+LCT】
- BZOJ.4817.[SDOI2017]树点涂色(LCT DFS序 线段树)
- bzoj 4817: [Sdoi2017]树点涂色
- [SDOI2017][bzoj4817] 树点涂色 [LCT+线段树]
- bzoj4817: [Sdoi2017]树点涂色
- AC日记——[SDOI2017]树点涂色 bzoj 4817
- bzoj4817[Sdoi2017]树点涂色
- bzoj 4817: [Sdoi2017]树点涂色 link cut tree+线段树+树链剖分
- BZOJ 4817: [Sdoi2017]树点涂色
- [Bzoj4817] [Sdoi2017]树点涂色 (LCT神题)
- bzoj千题计划275:bzoj4817: [Sdoi2017]树点涂色
- [BZOJ4817][SDOI2017]树点涂色(LCT+DFS序线段树)
- bzoj4817 [Sdoi2017]树点涂色
- 【BZOJ4817】树点涂色(LCT,线段树,树链剖分)
- Bzoj4817 [Sdoi2017]树点涂色