正题

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)相关推荐

  1. jzoj4739-[雅礼联考GDOI2017模拟9.2]Ztxz16学图论【LCT,树状数组】

    正题 题目链接:https://gmoj.net/senior/#main/show/4739 题目大意 nnn个点mmm条边的一张图,qqq次询问一个区间的边可以形成多少连通块. 解题思路 询问按照 ...

  2. 「雅礼集训 2017 Day7」事情的相似度(后缀自动机+LCT+树状数组)

    description 点击查看题目内容 solution Step1 无脑建SAMSAMSAM 两个前缀的最长公共后缀就是parent−treeparent-treeparent−tree上两点的l ...

  3. 洛谷 - P2163 [SHOI2007]园丁的烦恼(不带修二维数点-树状数组/主席树)

    题目链接:点击查看 题目大意:二维平面坐标系中给出 nnn 个坐标点,然后是 mmm 次询问,每次询问需要回答一个闭合矩阵中有多少个点 题目分析:想挂树套树来着,但是复杂度有点大.本题不带修且可以离线 ...

  4. 树状数组(求子区间和+更新元素值)

    树状数组 欲完成修改值和查询区间和两种操作 求前缀和的做法时间复杂度为O(n)O(n)O(n) 使用树状数组时间复杂度降为O(logn)O(logn)O(logn) lowbit 1.x&(- ...

  5. poj 3167(KMP+树状数组)

    之前自己在做题的时候在网上找别人的题解,虽然当时理解,但时间一久就忘了.所以开个这个东西来记录自己的学习进程,方便自己的回顾,以及给他人提供题解. 开始冲击明年高二的省选!不再颓废! 好了,下面进入正 ...

  6. 洛谷 P5057 [CQOI2006]简单题(树状数组)

    嗯... 题目链接:https://www.luogu.org/problem/P5057 首先发现这道题中只有0和1,所以肯定与二进制有关.然后发现这道题需要支持区间更改和单点查询操作,所以首先想到 ...

  7. Color the ball(HDU1556)树状数组

    每次对区间内气球进行一次染色,求n次操作后后所有气球染色次数. 树状数组,上下区间更新都可以,差别不大. 1.对于[x,y]区间,对第x-1位减1,第y位加1,之后向上统计 #include<b ...

  8. 【BZOJ2434】[NOI2011]阿狸的打字机 AC自动机+DFS序+树状数组

    [BZOJ2434][NOI2011]阿狸的打字机 Description 阿狸喜欢收藏各种稀奇古怪的东西,最近他淘到一台老式的打字机.打字机上只有28个按键,分别印有26个小写英文字母和'B'.'P ...

  9. Codeforces 629D Babaei and Birthday Cake(树状数组优化dp)

    题意: 线段树做法 分析: 因为每次都是在当前位置的前缀区间查询最大值,所以可以直接用树状数组优化.比线段树快了12ms~ 代码: #include<cstdio> #include< ...

最新文章

  1. java升序问题_JAVA并发理解之重排序问题
  2. AI CC2019软件安装教程
  3. Hudson Jenkins 文档一篇[转记]
  4. 计算机代码如何使用方法,电脑定时自动关机代码怎么样使用
  5. AutoIT: 开发界面结合GUI automation和Watir Automation
  6. 少吃点真的能改变“命运”?
  7. HDU 4864 (2014 Multi-University Training Contest 1 )
  8. 报文分析4、TCP协议的头结构
  9. java查询mongodb数据_从mongodb中查询数据
  10. 微信小程序tabbar图片路径问题
  11. 如何成为一名研发主管--关于个人、过程、工具和团队之一
  12. 删除桌面上的天猫双十一图标
  13. Linux (deepin)网络管理详解
  14. Mysql创建用户并赋予权限
  15. 机器人设计之软件设计
  16. 基于WEB的网上在线图书商城
  17. 如何购买一台云服务器
  18. HBase NoSQL数据库详解
  19. 利用词向量计算上下位关系
  20. Pyside2中嵌入Matplotlib的绘图

热门文章

  1. gitee 从 拉取新分支到本地_Hexo博客详细教程(一)| 建立本地站点
  2. 两台思科交换机vlan划分_Cisco交换机Vlan划分及ACL配置详细步骤 | 吴文辉博客
  3. 在数组中找重复数、只出现一次的数或丢失数的题目(Leetcode题解-Python语言)
  4. [mybatis]Configuration XML_mappers
  5. [设计模式]命令模式
  6. C++ 实现分块查找(顺序存储结构)(完整代码)
  7. 《C++ Primer》1.52节练习
  8. 高等数学上-赵立军-北京大学出版社-题解-练习5.2
  9. Pseudoprime numbers POJ - 3641(快速幂+判素数)
  10. Ticket Game CodeForces - 1215D(博弈题,巴什博弈思维)