SDOI2017 树点涂色——LCT the END
Description
Input
Output
Sample Input
1 2
2 3
3 4
3 5
2 4 5
3 3
1 4
2 4 5
1 5
2 4 5
Sample Output
4
2
2
--by BZOJ
http://www.lydsy.com/JudgeOnline/problem.php?id=4817
大概自己也没想到会回来写这道题吧。
一直对之前见到的,没做出来的题挺抵触的,
不过这是不对的,
题做不出来,也正常,
谁还能把所有的题全做出来呢,
况且,我见到这个题时还不会LCT,
我当时已经打出了树链剖分做法的全部了,
当然爆了一两个点的栈,SD的省选嘛,
然而自己弱是不应该找理由的,
题做不出来就是弱,
没理由的,
那就不应该逃避了,
那么,如果我没有死,你们都将看到我;
如果用LCT记录颜色个数的话,会非常僵,大概只能解决树链剖分解决的问题,
也就是操作三之外的;
但在观察每一个时期树上的颜色情况,发现与LCT的结构类似;
于是考虑利用LCT的结构维护颜色;
对于一二操作;
一就是从某点ACCESS;
二就是从某点空跑ACCESS而不改变splay的组成;
考虑一对三的影响:
发现在ACCESS连接两个点时,父方的点的原儿子的子树到根的颜色数+1,儿子方的点自己的子树颜色树减一;
维护线段树即可;
代码:
#include<cstdio>
using namespace std;
int max[],mark[],rank[],dep[],size[],a[];
struct dt{
int fa,ch[];
}data[];
struct ss{
int to,next;
}e[];
int first[],num;
int n,m;
void build(int ,int );
void dfs(int ,int ,int );
void builine(int ,int ,int );
void access(int );
int find_top(int );
void splay(int );
void roll(int );
void find(int ,int );
void add(int ,int ,int ,int ,int ,int );
int ans(int ,int ,int ,int ,int );
void down(int );
inline void in(int &ans)
{
ans=;bool p=false;char ch=getchar();
while((ch>'' || ch<'')&&ch!='-') ch=getchar();
if(ch=='-') p=true,ch=getchar();
while(ch<=''&&ch>='') ans=ans*+ch-'',ch=getchar();
if(p) ans=-ans;
}
int main()
{
int i,j,k,x,y;
in(n),in(m);
for(i=;i<=n-;i++){
in(j),in(k);
build(j,k);build(k,j);
}
num=;dfs(,,);
num=;builine(,n,);
for(i=;i<=m;i++){
in(j);
if(j==){
in(x);
access(x);
}
if(j==){
in(x),in(y);
find(x,y);
}
if(j==){
in(x);
y=ans(,n,,rank[x],rank[x]+size[x]-);
printf("%d\n",y);
}
}
return ;
}
void build(int f,int t){
e[++num].next=first[f];
e[num].to=t;
first[f]=num;
}
void dfs(int now,int d,int fa){
int i;
dep[now]=d;size[now]=;rank[now]=++num;a[num]=now;data[now].fa=fa;
for(i=first[now];i;i=e[i].next)
if(e[i].to!=fa){
dfs(e[i].to,d+,now);
size[now]+=size[e[i].to];
}
}
void builine(int l,int r,int nu){
if(l==r){
max[nu]=dep[a[++num]];
return ;
}
int mid=(l+r)>>;
builine(l,mid,nu<<);
builine(mid+,r,nu<<|);
max[nu]=max[nu<<]>max[nu<<|]?max[nu<<]:max[nu<<|];
}
void access(int x){
int y=,z;
while(x){
splay(x);z=find_top(y);
if(z)add(,n,,rank[z],rank[z]+size[z]-,-);
z=data[x].ch[];
data[x].ch[]=y;
y=x;x=data[x].fa;
z=find_top(z);
if(z)add(,n,,rank[z],rank[z]+size[z]-,);
}
}
int find_top(int x){
splay(x);
while(data[x].ch[])
x=data[x].ch[];
return x;
}
void splay(int x){
if(!x)return ;
int fa,fafa;
fa=data[x].fa;fafa=data[fa].fa;
for(;data[fa].ch[]==x||data[fa].ch[]==x;roll(x),fa=data[x].fa,fafa=data[fa].fa){
if(data[fafa].ch[]==fa||data[fafa].ch[]==fa){
if((data[fafa].ch[]==fa)^(data[fa].ch[]==x))
roll(x);
else
roll(fa);
}
}
}
void roll(int now){
int fa=data[now].fa,fafa=data[fa].fa,wh=data[fa].ch[]==now;
data[fa].ch[wh]=data[now].ch[wh^];data[data[fa].ch[wh]].fa=fa;
data[now].ch[wh^]=fa;data[fa].fa=now;
data[now].fa=fafa;
if (data[fafa].ch[]==fa||data[fafa].ch[]==fa)
data[fafa].ch[data[fafa].ch[]==fa]=now;
}
void find(int x,int y){
int ans=;
x=find_top(x);y=find_top(y);
while(x!=y){
if(dep[x]>dep[y]){
splay(x);x=find_top(data[x].fa);ans++;
}
else{
splay(y);y=find_top(data[y].fa);ans++;
}
}
printf("%d\n",ans);
}
void add(int l,int r,int nu,int L,int R,int x){
if(L<=l&&r<=R){
max[nu]+=x;
mark[nu]+=x;
return ;
}
int mid=(l+r)>>;
down(nu);
if(L<=mid)
add(l,mid,nu<<,L,R,x);
if(R>mid)
add(mid+,r,nu<<|,L,R,x);
max[nu]=max[nu<<]>max[nu<<|]?max[nu<<]:max[nu<<|];
}
int ans(int l,int r,int nu,int L,int R){
if(L<=l&&r<=R)
return max[nu];
int mid=(l+r)>>,lm=,rm=;
down(nu);
if(L<=mid)
lm=ans(l,mid,nu<<,L,R);
if(R>mid)
rm=ans(mid+,r,nu<<|,L,R);
if(lm>rm)return lm;
return rm;
}
void down(int nu){
if(!mark[nu])return;
max[nu<<]+=mark[nu];max[nu<<|]+=mark[nu];
mark[nu<<]+=mark[nu];mark[nu<<|]+=mark[nu];
mark[nu]=;
}
SDOI2017 树点涂色——LCT the END的更多相关文章
- [Sdoi2017]树点涂色 [lct 线段树]
		[Sdoi2017]树点涂色 题意:一棵有根树,支持x到根染成新颜色,求x到y颜色数,求x子树里点到根颜色数最大值 考场发现这个信息是可减的,但是没想到lct 特意设计成lct的形式! 如何求颜色数? ... 
- [BZOJ4817][SDOI2017]树点涂色(LCT+DFS序线段树)
		4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 692 Solved: 408[Submit][Status ... 
- 【BZOJ4817】[Sdoi2017]树点涂色 LCT+线段树
		[BZOJ4817][Sdoi2017]树点涂色 Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路径的权值是:这条路 ... 
- BZOJ 4817 [SDOI2017]树点涂色 (LCT+线段树维护dfs序)
		题目大意:略 涂色方式明显符合$LCT$里$access$操作的性质,相同颜色的节点在一条深度递增的链上 用$LCT$维护一个树上集合就好 因为它维护了树上集合,所以它别的啥都干不了了 发现树是静态的 ... 
- BZOJ4817[Sdoi2017]树点涂色——LCT+线段树
		题目描述 Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色.Bob可能会进 ... 
- P3703 [SDOI2017]树点涂色  LCT维护颜色+线段树维护dfs序+倍增LCA
		\(\color{#0066ff}{ 题目描述 }\) Bob有一棵\(n\)个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是:这条路径上的点 ... 
- BZOJ 4817: [Sdoi2017]树点涂色  LCT+Access的性质+DFS序+线段树
		Code: #include<bits/stdc++.h> #define maxn 200003 #define inf -1000000 using namespace std; vo ... 
- BZOJ.4817.[SDOI2017]树点涂色(LCT DFS序 线段树)
		题目链接 操作\(1.2\)裸树剖,但是操作\(3\)每个点的答案\(val\)很不好维护.. 如果我们把同种颜色的点划分到同一连通块中,那么向根染色的过程就是Access()! 最初所有点间都是虚边 ... 
- 【bzoj4817】[Sdoi2017]树点涂色  LCT+LCA+线段树
		题目描述 给出一棵n个点,以1为根的有根树,每个点初始染有互不相同的颜色.定义一条路径的权值为路径上的颜色种类数.现有m次操作,每次操作为以下三种之一: 1 x: 把点x到根节点的路径上所有的点染上一 ... 
随机推荐
- Java网络编程以及简单的聊天程序
			网络编程技术是互联网技术中的主流编程技术之一,懂的一些基本的操作是非常必要的.这章主要讲解网络编程,UDP和Socket编程,以及使用Socket做一个简单的聊天软件. 全部代码下载:链接 1.网络编 ... 
- 队列的理解和实现(一) ----- 循环队列(java实现)
			什么是队列 我们都知道栈是先进后出的一种线性表,与之相反的是,队列是一种先进先出的线性表.它只允许在表的一端进行插入,而在另一端进行删除.举个例子来说,在生活中我们买东西需要进行排队,最先排队的可以最 ... 
- 2016级算法期末上机-A.简单·Bamboo's Fight with DDLs I
			简单·Bamboo's Fight with DDLs I 分析 一句话:要装满的完全背包问题. 对比完全背包只有一点要改变:初始化为负无穷 传送门: https://buaacoding.cn/pr ... 
- mariadb配置主从同步遇到的问题
			一:ERROR: No query specified 解决方案: \G后面不能再加分号;,因为\G在功能上等同于;,如果加了分号,那么就是;;(2个分号),SQL语法错误 二:主从同步不成功 Sla ... 
- 浅谈postMessage跨域通信与localStorage实现跨域共享
			https://www.cnblogs.com/tyrion1990/p/8134384.html 
- anyncTask的3个参数(从源码可以发现其中使用了ThreadPoolExcuter线程池)
			AnyncTask异步处理数据并将数据应用到视图的操作场合 一 其中包含这几个方法 1 onPreExcute() 初始化控件,例如进度条2 doInBackground() 具体的执行动作请求数据 ... 
- Wrapper配置详解及高级应用(转)
			转自:http://286.iteye.com/blog/1921414 将一个简单的程度如HelloWorld 的应用包装秤Wrapper 服务并不复杂,甚至可以认为非常简单.但是实际项目应用过程中 ... 
- Hibernate中Query.list()方法报IllegalArgumentException异常
			最近在使用Hibernate开发项目,在写好hql语句,并初始化Query对象,执行Query.list()方法时,应用报IllegalArgumentException异常.经网上查询,现已经基本决 ... 
- Python 两种获取文件大小的方法
			import os r=os.path.getsize("/root/catbird1.stl") f=open("/root/catbird1.stl",&q ... 
- Javac之Environment
			关于Env的源代码如下: /** A class for environments, instances of which are passed as * arguments to tree visi ... 
