【LCT】【树状数组】Matches Are Not a Child‘s Play(luogu CF1137F)
生活随笔
收集整理的這篇文章主要介紹了
【LCT】【树状数组】Matches Are Not a Child‘s Play(luogu CF1137F)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
正題
luogu CF1137F
題目大意
定義一棵樹的產出序列為依次刪除權值最小的葉子節點的順序
進行q此操作:
1.把一個點的權值改為當前樹中的最大權值+1
2.查詢一個點在刪除序列中的位置
3.給出兩個點,查詢哪個在刪除序列中的位置更前
解題思路
假設已經求出了刪除序列,且最大權值的點為y,那么修改一個點x,相當于把x~y上的點放到序列后面(對于其它點,必然不是在x或y刪除后再刪除的)
這就是要提取出一條樹鏈,可以使用LCT
以權值最大的點為根節點,一個點往上若干個權值比它小的點為一條鏈,因為這些點要會當前點刪除后依次刪除(當前點刪除了,那么其它葉子結點一定都大于當前點,也就大于鏈上其它點)
給這條鏈上的所有點的顏色染上鏈上最深點的權值
那么查詢就相當于查找顏色比當它小的點的個數加上鏈上比它深的點的個數
修改就相當于連接x~y的鏈,換根,染色
對于查找顏色比它小的點用樹狀數組即可
代碼
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define N 200021 using namespace std; int n, q, x, y, w, tot, cl[N], head[N]; string str; struct rec {int to, next; }a[N<<1]; struct tree//樹狀數組 {int n, c[N<<1];void change(int x, int y){for (; x <= n; x += x&-x)c[x] += y;return;}int ask(int x){int sum = 0;for (; x; x -= x&-x)sum += c[x];return sum;} }t; struct LCT {int p[N], fa[N], sz[N], son[N][2];bool NR(int x){return fa[x] && (son[fa[x]][0] == x || son[fa[x]][1] == x);}bool IRS(int x){return son[fa[x]][1] == x;}void push_up(int x){sz[x] = sz[son[x][0]] + sz[son[x][1]] + 1;return;}void pushr(int x){p[x] ^= 1;swap(son[x][0], son[x][1]);return;}void push_down(int x){if (son[x][0]) cl[son[x][0]] = cl[x];//顏色if (son[x][1]) cl[son[x][1]] = cl[x];if (p[x]){if (son[x][0]) pushr(son[x][0]);if (son[x][1]) pushr(son[x][1]);p[x] = 0;}return;}void push_hall(int x){if (NR(x)) push_hall(fa[x]);push_down(x);return;}void rotate(int x){int y = fa[x], z = fa[y], k = IRS(x), g = son[x][!k];if (NR(y)) son[z][IRS(y)] = x;if (g) fa[g] = y;fa[x] = z;fa[y] = x;son[x][!k] = y;son[y][k] = g;push_up(y);return;}void Splay(int x){push_hall(x);while(NR(x)){if (NR(fa[x])) rotate(IRS(x) == IRS(fa[x]) ? fa[x] : x);rotate(x);}push_up(x);}void access(int x){for (int y = 0; x; x = fa[y = x]){Splay(x);son[x][1] = 0;push_up(x);t.change(cl[x], -sz[x]);//減去原來的顏色t.change(w, sz[x]);//改成現在的顏色son[x][1] = y;push_up(x);}return;}void make_root(int x){w++;access(x);Splay(x);cl[x] = w;//染色pushr(x);return;}int ask(int x){Splay(x);return sz[son[x][1]] + 1 + t.ask(cl[x] - 1);} }T; void add(int x, int y) {a[++tot].to = y;a[tot].next = head[x];head[x] = tot;return; } void dfs(int x) {cl[x] = x;for (int i = head[x]; i; i = a[i].next)if (!cl[a[i].to]){T.fa[a[i].to] = x;dfs(a[i].to);if (cl[a[i].to] > cl[x]){cl[x] = cl[a[i].to];T.son[x][1] = a[i].to;}}t.change(cl[x], 1);T.push_up(x);return; } int main() {scanf("%d%d", &n, &q);for (int i = 1; i < n; ++i){scanf("%d%d", &x, &y);add(x, y);add(y, x);}t.n = n + q;w = n;dfs(n);//連初始的圖while(q--){cin>>str;if (str == "up"){scanf("%d", &x);T.make_root(x);}else if (str == "when"){scanf("%d", &x);printf("%d\n", T.ask(x));}else{scanf("%d%d", &x, &y);printf("%d\n", T.ask(x) < T.ask(y) ? x : y);}}return 0; }總結
以上是生活随笔為你收集整理的【LCT】【树状数组】Matches Are Not a Child‘s Play(luogu CF1137F)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 九龙壁在哪 九龙壁在哪一个位置
- 下一篇: 【bfs】重力球(luogu 7473/