BZOJ4817[Sdoi2017]树点涂色——LCT+线段树
题目描述
输入
输出
样例输入
1 2
2 3
3 4
3 5
2 4 5
3 3
1 4
2 4 5
1 5
2 4 5
样例输出
4
2
2
- #include<set>
- #include<map>
- #include<queue>
- #include<stack>
- #include<cmath>
- #include<cstdio>
- #include<bitset>
- #include<vector>
- #include<cstring>
- #include<iostream>
- #include<algorithm>
- #define ll long long
- using namespace std;
- int c[100010][2];
- int fa[100010];
- int tag[400010];
- int f[100010][18];
- int dep[100010];
- int mx[400010];
- int dfn;
- int tot;
- int x,y;
- int n,m;
- int opt;
- int head[100010];
- int next[200010];
- int to[200010];
- int q[100010];
- int s[100010];
- int t[100010];
- void add(int x,int y)
- {
- next[++tot]=head[x];
- head[x]=tot;
- to[tot]=y;
- }
- void pushup(int rt)
- {
- mx[rt]=max(mx[rt<<1],mx[rt<<1|1]);
- }
- void pushdown(int rt)
- {
- if(tag[rt])
- {
- tag[rt<<1]+=tag[rt];
- tag[rt<<1|1]+=tag[rt];
- mx[rt<<1]+=tag[rt];
- mx[rt<<1|1]+=tag[rt];
- tag[rt]=0;
- }
- }
- void build(int rt,int l,int r)
- {
- if(l==r)
- {
- mx[rt]=dep[q[l]];
- return ;
- }
- int mid=(l+r)>>1;
- build(rt<<1,l,mid);
- build(rt<<1|1,mid+1,r);
- pushup(rt);
- }
- void change(int rt,int l,int r,int L,int R,int v)
- {
- if(L<=l&&r<=R)
- {
- tag[rt]+=v;
- mx[rt]+=v;
- return ;
- }
- pushdown(rt);
- int mid=(l+r)>>1;
- if(L<=mid)
- {
- change(rt<<1,l,mid,L,R,v);
- }
- if(R>mid)
- {
- change(rt<<1|1,mid+1,r,L,R,v);
- }
- pushup(rt);
- }
- int query(int rt,int l,int r,int L,int R)
- {
- if(L<=l&&r<=R)
- {
- return mx[rt];
- }
- pushdown(rt);
- int mid=(l+r)>>1;
- int res=0;
- if(L<=mid)
- {
- res=max(res,query(rt<<1,l,mid,L,R));
- }
- if(R>mid)
- {
- res=max(res,query(rt<<1|1,mid+1,r,L,R));
- }
- return res;
- }
- int ask(int rt,int l,int r,int k)
- {
- if(l==r)
- {
- return mx[rt];
- }
- pushdown(rt);
- int mid=(l+r)>>1;
- if(k<=mid)
- {
- return ask(rt<<1,l,mid,k);
- }
- else
- {
- return ask(rt<<1|1,mid+1,r,k);
- }
- }
- bool is_root(int rt)
- {
- return rt!=c[fa[rt]][0]&&rt!=c[fa[rt]][1];
- }
- bool get(int rt)
- {
- return rt==c[fa[rt]][1];
- }
- void rotate(int rt)
- {
- int x=fa[rt];
- int y=fa[x];
- int k=get(rt);
- if(!is_root(x))
- {
- c[y][get(x)]=rt;
- }
- c[x][k]=c[rt][k^1];
- fa[c[rt][k^1]]=x;
- c[rt][k^1]=x;
- fa[x]=rt;
- fa[rt]=y;
- }
- void splay(int rt)
- {
- for(int x;!is_root(rt);rotate(rt))
- {
- if(!is_root(x=fa[rt]))
- {
- rotate(get(x)==get(rt)?x:rt);
- }
- }
- }
- void link(int x,int y)
- {
- fa[x]=y;
- }
- int find(int rt)
- {
- while(c[rt][0])
- {
- rt=c[rt][0];
- }
- return rt;
- }
- void access(int rt)
- {
- for(int x=0;rt;x=rt,rt=fa[rt])
- {
- splay(rt);
- if(x)
- {
- int son=find(x);
- change(1,1,n,s[son],t[son],-1);
- }
- if(c[rt][1])
- {
- int son=find(c[rt][1]);
- change(1,1,n,s[son],t[son],1);
- }
- c[rt][1]=x;
- }
- }
- void dfs(int x)
- {
- s[x]=++dfn;
- q[dfn]=x;
- for(int i=1;i<=17;i++)
- {
- f[x][i]=f[f[x][i-1]][i-1];
- }
- for(int i=head[x];i;i=next[i])
- {
- if(to[i]!=f[x][0])
- {
- f[to[i]][0]=x;
- link(to[i],x);
- dep[to[i]]=dep[x]+1;
- dfs(to[i]);
- }
- }
- t[x]=dfn;
- }
- int lca(int x,int y)
- {
- if(dep[x]<dep[y])
- {
- swap(x,y);
- }
- int d=dep[x]-dep[y];
- for(int i=0;i<=17;i++)
- {
- if(d&(1<<i))
- {
- x=f[x][i];
- }
- }
- if(x==y)
- {
- return x;
- }
- for(int i=17;i>=0;i--)
- {
- if(f[x][i]!=f[y][i])
- {
- x=f[x][i];
- y=f[y][i];
- }
- }
- return f[x][0];
- }
- int main()
- {
- scanf("%d%d",&n,&m);
- for(int i=1;i<n;i++)
- {
- scanf("%d%d",&x,&y);
- add(x,y);
- add(y,x);
- }
- dep[1]=1;
- dfs(1);
- build(1,1,n);
- while(m--)
- {
- scanf("%d",&opt);
- if(opt==1)
- {
- scanf("%d",&x);
- access(x);
- }
- else if(opt==2)
- {
- scanf("%d%d",&x,&y);
- int anc=lca(x,y);
- int ans=ask(1,1,n,s[x])+ask(1,1,n,s[y])-2*ask(1,1,n,s[anc])+1;
- printf("%d\n",ans);
- }
- else
- {
- scanf("%d",&x);
- printf("%d\n",query(1,1,n,s[x],t[x]));
- }
- }
- }
BZOJ4817[Sdoi2017]树点涂色——LCT+线段树的更多相关文章
- 【BZOJ4817】[Sdoi2017]树点涂色 LCT+线段树
[BZOJ4817][Sdoi2017]树点涂色 Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路 ...
- 【BZOJ4817】【SDOI2017】树点涂色 [LCT][线段树]
树点涂色 Time Limit: 10 Sec Memory Limit: 128 MB[Submit][Status][Discuss] Description Bob有一棵n个点的有根树,其中1 ...
- [Sdoi2017]树点涂色 [lct 线段树]
[Sdoi2017]树点涂色 题意:一棵有根树,支持x到根染成新颜色,求x到y颜色数,求x子树里点到根颜色数最大值 考场发现这个信息是可减的,但是没想到lct 特意设计成lct的形式! 如何求颜色数? ...
- [SDOI2017][bzoj4817] 树点涂色 [LCT+线段树]
题面 传送门 思路 $LCT$ 我们发现,这个1操作,好像非常像$LCT$里面的$Access$啊~ 那么我们尝试把$Access$操作魔改成本题中的涂色 我们令$LCT$中的每一个$splay$链代 ...
- bzoj4817 & loj2001 [Sdoi2017]树点涂色 LCT + 线段树
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4817 https://loj.ac/problem/2001 题解 可以发现这个题就是 bzo ...
- BZOJ 4817 [SDOI2017]树点涂色 (LCT+线段树维护dfs序)
题目大意:略 涂色方式明显符合$LCT$里$access$操作的性质,相同颜色的节点在一条深度递增的链上 用$LCT$维护一个树上集合就好 因为它维护了树上集合,所以它别的啥都干不了了 发现树是静态的 ...
- 【bzoj4817】树点涂色 LCT+线段树+dfs序
Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...
- BZOJ 4817 [Sdoi2017]树点涂色 ——LCT 线段树
同BZOJ3779. SDOI出原题,还是弱化版的. 吃枣药丸 #include <map> #include <cmath> #include <queue> # ...
- BZOJ 4817: [Sdoi2017]树点涂色(lct+线段树)
传送门 解题思路 跟重组病毒这道题很像.只是有了一个询问\(2\)的操作,然后询问\(2\)的答案其实就是\(val[x]+val[y]-2*val[lca(x,y)]+1\)(画图理解).剩下的操作 ...
随机推荐
- 荣耀MagicBook黑苹果(i7)High Sierra 10.13.6
这里有大佬维护的新版本EFI,对应10.14.4:https://github.com/hjmmc/Honor-Magicbook ---------------------------------- ...
- 【20190405】JavaScript-整理一些常用正则式
匹配中文字符: let reg=/([\u4E00-\u9FFF]+)/; //\u代表Unicode编码 匹配电话号码: let reg=/^1[34578]\d{9}$/; 给每三位数字添加一个逗 ...
- 驰骋工作流引擎JFlow与activiti的对比 -总结
共同点: 1. 嵌入式的工作流引擎,降低集群复杂性. 2. 严格而灵活的流程版本控制 3. 支持多种数据库 4. 支持多种流程设计模式 5. 成熟度高的开源工作流,具有可靠的稳定性和性能. 区别: 1 ...
- 在IIS上部署你的ASP.NET Core 2.1项目
1.在控制面板→程序→启用或关闭Windows功能→勾选Internet Information Services以及Web管理工具下的IIS管理控制台 2.IIS 安装AspNetCoreModul ...
- Arcgis瓦片--数据获取
Arcgis的二维地图瓦片有两种获取方式 1.在Arcmap中对配置好的地图进行切图,生成对应瓦片 2.使用第三方的地图下载器,直接下载,导出成arcgis瓦片格式即可使用. 备注:这里主要介绍第二种 ...
- 企业信息化-Excel快速生成系统
企业信息化,主要是指对企业生产运营过程所形成的信息数字化,最终形成了数字资产.大型企业为了节约成本,提高协同工作效率,都会定制ERP.办公OA.流程审批等系统做信息化支撑.但是中小企业精力投入到生成中 ...
- win快捷键
******************键盘快捷键大全****************** 一.常见用法: F1 显示当前程序或者windows的帮助内容. F2 当你选中一个文件的话,这意味着“重命名 ...
- huffman树即Huffma编码的实现
自己写的Huffman树生成与Huffman编码实现 (实现了核心功能 ,打出了每个字符的huffman编码 其他的懒得实现了,有兴趣的朋友可以自己在我的基础增加功能 ) /* 原创文章 转载请附上原 ...
- MS SQL自定义函数判断是否正整数
可以写一个函数: 主要是使用正则来判断.另外输入字符是空的话,使用"-"来替换. CREATE FUNCTION [dbo].[svf_NonNegativeInteger] ( ...
- MySQL常用数值函数
数值函数: 用来处理很多数值方面的运算,使用数值函数,可以免去很多繁杂的判断求值的过程,能够大大提高用户的工作效率. 1.ABS(x):返回 x 的绝对值 mysql> select abs(- ...