显然compare操作可以通过两次when操作实现,以下仅考虑前两种操作

为了方便,将优先级最高的节点作为根,显然根最后才会被删除

接下来,不断找到剩下的节点中(包括根)优先级最高的节点,将其到其所在树根的所有节点从下到上依次加入到序列的开头并删除,不难发现最终得到的序列即为燃烧的顺序

将每一次删除的链上的边称为实边,其余边称为虚边,实际上就构成了一个类似于LCT的结构

一次$v$的修改操作对该LCT的影响,简单分析后不难发现即为将$v$换为根

考虑节点$v$的答案,即分为两部分:

1.定义其中一条实链(一个Splay)的优先级为其中优先级最大的节点(链尾),所有实链中优先级比$v$所在实链小的长度(指节点个数)和

2.$v$所在实链中比$v$浅的点个数(包括$v$自身)

前者可以在LCT修改的过程中再维护一个树状数组(以优先级为下标,长度为权值),后者直接在LCT中查询该节点(将其Splay到根)即可,将两者求和即为答案

时间复杂度为$o(n\log n)$,可以通过

  1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 200005
4 struct Edge{
5 int nex,to;
6 }edge[N<<1];
7 int E,n,m,x,y,head[N],f[N<<1],st[N],fa[N],val[N],sz[N],rev[N],ch[N][2];
8 char s[11];
9 int lowbit(int k){
10 return (k&(-k));
11 }
12 void update(int k,int x){
13 while (k<=n+m){
14 f[k]+=x;
15 k+=lowbit(k);
16 }
17 }
18 int query(int k){
19 int ans=0;
20 while (k){
21 ans+=f[k];
22 k-=lowbit(k);
23 }
24 return ans;
25 }
26 int which(int k){
27 return ch[fa[k]][1]==k;
28 }
29 int check(int k){//返回1当且仅当不是根节点
30 return ch[fa[k]][which(k)]==k;
31 }
32 void upd(int k){
33 rev[k]^=1;
34 swap(ch[k][0],ch[k][1]);
35 }
36 void up(int k){
37 sz[k]=sz[ch[k][0]]+sz[ch[k][1]]+1;
38 }
39 void down(int k){
40 if (ch[k][0])val[ch[k][0]]=val[k];
41 if (ch[k][1])val[ch[k][1]]=val[k];
42 if (rev[k]){
43 upd(ch[k][0]);
44 upd(ch[k][1]);
45 rev[k]=0;
46 }
47 }
48 void rotate(int k){
49 int f=fa[k],g=fa[f],p=which(k);
50 fa[k]=g;
51 if (check(f))ch[g][which(f)]=k;
52 fa[ch[k][p^1]]=f,ch[f][p]=ch[k][p^1];
53 fa[f]=k,ch[k][p^1]=f;
54 up(f),up(k);
55 }
56 void splay(int k){
57 for(int i=k;;i=fa[i]){
58 st[++st[0]]=i;
59 if (!check(i))break;
60 }
61 while (st[0])down(st[st[0]--]);
62 for(int i=fa[k];check(k);i=fa[k]){
63 if (check(i)){
64 if (which(k)==which(i))rotate(i);
65 else rotate(k);
66 }
67 rotate(k);
68 }
69 }
70 void access(int k){
71 int lst=0;
72 while (k){
73 splay(k);
74 update(val[k],sz[ch[k][1]]-sz[k]);
75 ch[k][1]=lst,up(k);
76 lst=k,k=fa[k];
77 }
78 }
79 void make_root(int k){
80 access(k);
81 splay(k);
82 upd(k);
83 }
84 void add(int x,int y){
85 edge[E].nex=head[x];
86 edge[E].to=y;
87 head[x]=E++;
88 }
89 void dfs(int k,int f){
90 fa[k]=f,val[k]=k;
91 for(int i=head[k];i!=-1;i=edge[i].nex)
92 if (edge[i].to!=f){
93 dfs(edge[i].to,k);
94 val[k]=max(val[k],val[edge[i].to]);
95 }
96 update(val[k],1);
97 if (val[k]==k){
98 sz[k]=1;
99 return;
100 }
101 for(int i=head[k];i!=-1;i=edge[i].nex)
102 if ((edge[i].to!=f)&&(val[k]==val[edge[i].to])){
103 sz[k]=sz[edge[i].to]+1;
104 ch[k][1]=edge[i].to;
105 return;
106 }
107 }
108 void Update(int k){
109 make_root(k);
110 val[k]=++val[0];
111 update(val[k],sz[k]);
112 }
113 int Query(int k){
114 splay(k);
115 return query(val[k])-sz[ch[k][0]];
116 }
117 int main(){
118 scanf("%d%d",&n,&m);
119 memset(head,-1,sizeof(head));
120 for(int i=1;i<n;i++){
121 scanf("%d%d",&x,&y);
122 add(x,y),add(y,x);
123 }
124 dfs(n,0);
125 val[0]=n;
126 for(int i=1;i<=m;i++){
127 scanf("%s%d",s,&x);
128 if (s[0]=='u')Update(x);
129 if (s[0]=='w')printf("%d\n",Query(x));
130 if (s[0]=='c'){
131 scanf("%d",&y);
132 if (Query(x)<Query(y))printf("%d\n",x);
133 else printf("%d\n",y);
134 }
135 }
136 return 0;
137 }

[cf1137F]Matches Are Not a Child's Pla的更多相关文章

  1. CF1137F Matches Are Not a Child's Play(LCT思维题)

    题目 CF1137F 很有意思的题目 做法 直接考虑带修改的做法,上一次最大值为u,这次修改v,则最大值为v了 我们发现:\(u-v\)这条链会留到最后,序列里的其他元素相对位置不变,这条链会\(u\ ...

  2. CF1137F Matches Are Not a Child's Play(树链剖分)

    题面 我们定义一棵树的删除序列为:每一次将树中编号最小的叶子删掉,将该节点编号加入到当前序列的最末端,最后只剩下一个节点时将该节点的编号加入到结尾. 例如对于上图中的树,它的删除序列为:2 4 3 1 ...

  3. 【树链剖分 ODT】cf1137F. Matches Are Not a Child's Play

    孔爷的杂题系列:LCT清新题/ODT模板题 题目大意 定义一颗无根树的燃烧序列为:每次选取编号最小的叶子节点形成的序列. 要求支持操作:查询一个点$u$在燃烧序列中的排名:将一个点的编号变成最大 $n ...

  4. CF1137F Matches Are Not a Child's Play

    我们定义一棵树的删除序列为:每一次将树中编号最小的叶子删掉,将该节点编号加入到当前序列的最末端,最后只剩下一个节点时将该节点的编号加入到结尾.现在给出一棵n个节点的树,有m次操作: up v:将v号节 ...

  5. [Codeforces1137F]Matches Are Not a Child's Play——LCT+树状数组

    题目链接: [Codeforces1137F]Matches Are Not a Child's Play 题目大意: 我们定义一棵树的删除序列为:每一次将树中编号最小的叶子删掉,将该节点编号加入到当 ...

  6. Codeforces 1137F Matches Are Not a Child's Play [LCT]

    Codeforces 很好,通过这题对LCT的理解又深了一层. 思路 (有人说这是套路题,然而我没有见过/kk) 首先发现,删点可以从根那里往下删,非常难受,所以把权值最大的点提为根. 然后考虑\(x ...

  7. Codeforces 1137F - Matches Are Not a Child's Play(LCT)

    Codeforces 题面传送门 & 洛谷题面传送门 考虑将一个点 \(x\) 的编号变为当前所有点编号最大值 \(+1\) 会对每个点的删除时间产生怎么样的影响.由于编号最大的点肯定是最后一 ...

  8. LCT[Link-Cut-Tree学习笔记]

    部分摘抄于 FlashHu candy99 所以文章篇幅较长 请有足够的耐心(不是 其实不用学好splay再学LCT的-/kk (至少现在我平衡树靠fhq) 如果学splay的话- 也许我菜吧-LCT ...

  9. 多校联训 DS 专题

    CF1039D You Are Given a Tree 容易发现,当 \(k\) 不断增大时,答案不断减小,且 \(k\) 的答案不超过 \(\lfloor\frac {n}{k}\rfloor\) ...

随机推荐

  1. Java-多态(上)

    什么是多态 同一方法可以根据发送对象的不同而采取多种不同的行为方式 一个对象实际类型是确定的 但指向其引用类型却有很多 注意事项 多态是方法的多态 属性没有多态 父类和子类 有联系 类型转换异常 Cl ...

  2. 感恩笔记之二_SQL语句扩展功能

    前言导读: 本章是对SQL语句基础功能中,一些功能用法的扩展使用的总结,都是实际工作中一些经验的积累. 1 select列查询功能组合使用 --1 函数处理+列计算+列改名 select 函数(列) ...

  3. 6岁!是时候重新认识下Serverless了

    一.背景 Serverless 概念从2012年开始提出,真正推出相关云产品是2014年AWS推出Lambda.如果我们将 Serverless 比作一个婴儿,那么它已经6岁了. 虽然业界对Serve ...

  4. Apache ShardingSphere 元数据加载剖析

    唐国城 小米软件工程师,主要负责 MIUI 浏览器服务端研发工作.热爱开源,热爱技术,喜欢探索,热衷于研究学习各种开源中间件,很高兴能参与到 ShardingSphere 社区建设中,希望在社区中努力 ...

  5. 洛谷4719 【模板】动态dp 学习笔记(ddp 动态dp)

    qwq大概是混乱的一个题. 首先,还是从一个比较基础的想法开始想起. 如果每次暴力修改的话,那么每次就可以暴力树形dp 令\(dp[x][0/1]\)表示\(x\)的子树中,是否选择\(x\)这个点的 ...

  6. 回归本心QwQ背包问题luogu1776

    今天在这里说一下多重背包问题 对 之前一直没有怎么彻底理解 首先多重背包是什么?这里就不做过多的赘述了 朴素的多重背包的复杂度是\(O(n*m*\sum s[i])\),其中\(s[i]\)是每一件物 ...

  7. 工作3年的Java程序员,轻松拿到阿里P6Offer,只因为他搞明白了Redis这几个问题!!

    Redis中的多路复用模型 Redis6用到了多线程?那多线程应用在哪些地方,引入多线程后,又改如何保证线程安全性呢? 同时,如何在性能和线程安全性方面做好平衡? 关于Redis的单线程模型 在Red ...

  8. 掌握BeanShell,轻松处理jmeter中的数据

    作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15424558.html 博客主页:https://www.cnblogs.com/testero ...

  9. 测试小姐姐问我 gRPC 怎么用,我直接把这篇文章甩给了她

    原文链接: 测试小姐姐问我 gRPC 怎么用,我直接把这篇文章甩给了她 上篇文章 gRPC,爆赞 直接爆了,内容主要包括:简单的 gRPC 服务,流处理模式,验证器,Token 认证和证书认证. 在多 ...

  10. UltraSoft - Beta - 发布声明

    1. Beta版本更新内容 新功能 (1)消息中心页面 课程爬取到新DDL.资源时会以通知的方式通知用户,本次同步更新了哪些内容一目了然.此外,当被作为参与成员添加DDL时也会通知.一些系统通知也会放 ...