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到根节点的路径上所有的点染上一 ...
随机推荐
- Eureka客户端注册过程源码解析
微服务中注册中心是其重要的组成部分,那么客户端是如何注册到注册中心的呢,下面我们进入源码查看. 客户端的注册标志是@EnableDiscoveryClient,我们点进入注解查看 注解介绍这是开启Di ...
- docker微服务部署之:三,搭建Zuul微服务项目
docker微服务部署之:二.搭建文章微服务项目 一.新增demo_eureka模块,并编写代码 右键demo_parent->new->Module->Maven,选择Module ...
- 2016级算法第六次上机-A.Bamboo之寻找小金刚
Bamboo之寻找小金刚 分析 可以抽象为许多连续线段,分别计数左拐和右拐的个数.考察叉积的基础应用. 假设ABC三点构成一个夹角∠ABC,B就是拐点,AC是辅助形成夹角.考虑线段AB和BC形成的向量 ...
- 题解 p2420 让我们异或吧
传送门 #include<iostream> #include<cstdio> #include<cstring> using namespace std; ;in ...
- Linux终端没有GUI,使用matplotlib绘图
一.解决警告信息 ... _tkinter.TclError: no display name and no $DISPLAY environment variable 两种解决方法: 1.pytho ...
- dubbo学习笔记:快速搭建
搭建一个简单的dubbo服务 参考地址: dubbo官网:http://dubbo.apache.org/zh-cn/docs/user/references/registry/zookeeper.h ...
- 开源.net 混淆器ConfuserEx介绍 [转]
今天给大家介绍一个开源.net混淆器——ConfuserEx http://yck1509.github.io/ConfuserEx/ 由于项目中要用到.net 混淆器,网上搜寻了很多款,比如Dotf ...
- WebStorm 快键键
ctrl+/ 单行注释ctrl+shift+/ 块注释ctrl+shift+ +/- 展开/折叠ctrl+alt+L 格式化代码ctrl+shift+ up/down 上下移动句子 Alt+回车 导入 ...
- WebDriver+TestNG的一个典型例子
想让测试更加灵活,1. 可以配置使用任意支持的浏览器进行测试:2. 配置所有Google的URL:3. 配置搜索的关键字.修改后的代码: public class GoogleTest { WebDr ...
- android Application类的详细介绍(转)
在代码中经常看到application这个类,一直不知道这个是干什么用的,今天刚好有点时间,所以进行了详细的学习. 一.先对它的整体概念解释: 在android源码中对他的描述是; * Base cl ...