bzoj 4817: [Sdoi2017]树点涂色
来源:互联网 发布:最好用黑客linux系统 编辑:程序博客网 时间:2024/05/20 10:56
lct。
第一个操作就是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 400020int fst[N], vv[M], nxt[M], e;int L[N], R[N], lab[N], dc;int dep[N], fa[N][22];int ch[N][2], pre[N];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;}
0 0
- bzoj 4817: [Sdoi2017]树点涂色
- [LCT] BZOJ 4817 [Sdoi2017]树点涂色
- 4817: [Sdoi2017]树点涂色
- [SDOI2017]树点涂色
- [SDOI2017]树点涂色
- bzoj 4817: [Sdoi2017]树点涂色 link cut tree+线段树+树链剖分
- BZOJ4817 [Sdoi2017]树点涂色
- BZOJ4817: [Sdoi2017]树点涂色
- bzoj4817 [Sdoi2017]树点涂色
- [LCT] BZOJ4817.[Sdoi2017]树点涂色
- loj #2001. 「SDOI2017」树点涂色(LCT)
- [BZOJ4817][SDOI2017]树点涂色(DFS序+LCA+树剖+LCT)
- [线段树] BZOJ 4821 [Sdoi2017]相关分析
- [BZOJ]4821: [Sdoi2017]相关分析 线段树
- bzoj 4821: [Sdoi2017]相关分析 线段树
- [链分治 重链剖分 FWT] BZOJ 4911 [Sdoi2017]切树游戏
- [链分治][FWT][树链剖分] BZOJ 4911: [Sdoi2017]切树游戏
- BZOJ 1260涂色 paint
- 畅通工程续
- 短信验证----上行和下行
- request.getParameter("uname")和session.getAttribute("uname")有什么区别
- chalk
- Unity人物换阶段1(ReadyToUse)
- bzoj 4817: [Sdoi2017]树点涂色
- 收网——计算机网络原理
- 【Unity3D】利用物体碰撞检测、键盘输入处理完成平衡球游戏
- JAVA使用Dom4j实现字符串和xml文件相互转换
- 基础知识—表达式与语句-运算符
- LabVIEW数组的应用
- exports 和 module.exports 的详解
- hadoop学习(10)—— SSH协议
- BZOJ 4382 [Hash][TwoPointers]