不算学会lct。。。。。。

原题:

Bob有一棵n个点的有根树,其中1号点是根节点。Bob在每个点上涂了颜色,并且每个点上的颜色不同。定义一条路
径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色。Bob可能会进行这几种操作:
1 x:
把点x到根节点的路径上所有的点染上一种没有用过的新颜色。
2 x y:
求x到y的路径的权值。
3 x y:
在以x为根的子树中选择一个点,使得这个点到根节点的路径权值最大,求最大权值。
Bob一共会进行m次操作
1<=n,m<=100000
 
并不严格的lct,只需要access操作,而且链存在的意义也不是为了优化时间复杂度
恩所以一开始每个点都是一条链,表示每个点都是一个颜色
access就相当于点到根染成同一种颜色
求路径权值就在链上跳一跳即可
子树最大指的话就一开始就搞出dfs序和线段树,因为树的形态并没有改变,然后access的时候维护即可
代码:
 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int rd(){int z=,mk=; char ch=getchar();
while(ch<''||ch>''){if(ch=='-')mk=-; ch=getchar();}
while(ch>=''&&ch<=''){z=(z<<)+(z<<)+ch-''; ch=getchar();}
return z*mk;
}
struct edg{int nxt,y;}e[]; int lk[],ltp=;
inline void ist(int x,int y){ e[++ltp].nxt=lk[x],lk[x]=ltp,e[ltp].y=y;}
int n,m;
int fth[],chd[][],tpf[];
int acst[][],dp[],dod[],lod[],rod[],cod=;
int v[],vt[];
void dfs(int x){
dod[lod[x]=++cod]=x;
for(int i=lk[x];i;i=e[i].nxt)if(e[i].y!=acst[x][])
acst[e[i].y][]=fth[e[i].y]=x,dp[e[i].y]=dp[x]+,dfs(e[i].y);
rod[x]=cod;
}
int lca(int x,int y){
if(dp[x]<dp[y]) swap(x,y);
for(int i=,j=dp[x]-dp[y];i<=;++i)if((<<i)&j) x=acst[x][i];
for(int i=;i>=;--i)if(acst[x][i]!=acst[y][i])
x=acst[x][i],y=acst[y][i];
if(x==y) return x;
return acst[x][];
}
void pshd(int x){
v[x<<]+=vt[x],v[x<<|]+=vt[x];
vt[x<<]+=vt[x],vt[x<<|]+=vt[x];
vt[x]=;
}
void gtsgmttr(int x,int l,int r){
if(l==r){ v[x]=dp[dod[l]]+; return ;}
int md=(l+r)>>;
gtsgmttr(x<<,l,md),gtsgmttr(x<<|,md+,r);
v[x]=max(v[x<<],v[x<<|]);
}
void mdf(int x,int l,int r,int ql,int qr,int z){
if(l==ql && r==qr){ v[x]+=z,vt[x]+=z; return ;}
int md=(l+r)>>; pshd(x);
if(ql<=md && qr>md) mdf(x<<,l,md,ql,md,z),mdf(x<<|,md+,r,md+,qr,z);
else if(qr<=md) mdf(x<<,l,md,ql,qr,z);
else mdf(x<<|,md+,r,ql,qr,z);
v[x]=max(v[x<<],v[x<<|]);
}
int qur(int x,int l,int r,int ql,int qr){
if(l==ql && r==qr) return v[x];
int md=(l+r)>>; pshd(x);
if(ql<=md && qr>md) return max(qur(x<<,l,md,ql,md),qur(x<<|,md+,r,md+,qr));
else if(qr<=md) return qur(x<<,l,md,ql,qr);
else return qur(x<<|,md+,r,ql,qr);
}
inline bool isrt(int x){ return (chd[fth[x]][]!=x)&(chd[fth[x]][]!=x);}
void pshu(int x){ tpf[x]=chd[x][] ? tpf[chd[x][]] : x;}
void rtt(int x){
int y=fth[x],z=fth[fth[x]],l,r;
r=(chd[y][]==x); l=r^;
if(!isrt(y)) chd[z][chd[z][]==y]=x;
fth[x]=z,fth[y]=x,fth[chd[x][r]]=y;
chd[y][l]=chd[x][r],chd[x][r]=y;
pshu(y),pshu(x);
}
void sply(int x){
while(!isrt(x)){
int y=fth[x],z=fth[fth[x]];
if(!isrt(y)) rtt((chd[y][]==x)^(chd[z][]==y) ? x : y);
rtt(x);
}
}
void accs(int x){
int lst=;
while(x){
sply(x);
if(chd[x][]) mdf(,,n,lod[tpf[chd[x][]]],rod[tpf[chd[x][]]],);
if(lst) mdf(,,n,lod[tpf[lst]],rod[tpf[lst]],-);
chd[x][]=lst,x=fth[lst=x];
}
}
int gtnm(int x){
int bwl=;
while(x){
sply(x);
x=fth[x],++bwl;
}
return bwl;
}
int cclt(int x,int y){
int z=lca(x,y);
return gtnm(x)+gtnm(y)-(gtnm(z)<<)+;
}
int main(){//freopen("ddd.in","r",stdin);
int l,r,mk;
cin>>n>>m;
for(int i=;i<n;++i) l=rd(),r=rd(),ist(l,r),ist(r,l);
dfs(),gtsgmttr(,,n);
for(int i=;i<=n;++i) tpf[i]=i;
for(int i=;i<=n;++i)for(int j=;(<<j)<=dp[i];++j)
acst[i][j]=acst[acst[i][j-]][j-];
while(m--){
mk=rd();
if(mk==) accs(rd());
else if(mk==) printf("%d\n",cclt(rd(),rd()));
else l=rd(),printf("%d\n",qur(,,n,lod[l],rod[l]));
}
return ;
}

【BZOJ4817】【SDOI2017】树点染色的更多相关文章

  1. SDOI2017 树点染色

    \[SDOI2017 树点染色\] 题目描述 Bob 有一棵 $ n $ 个点的有根树,其中 $ 1 $ 号点是根节点.Bob 在每个节点上涂了颜色,并且每个点上的颜色不同. 定义一条路径的权值是,这 ...

  2. [BZOJ4817][SDOI2017]树点涂色(LCT+DFS序线段树)

    4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 692  Solved: 408[Submit][Status ...

  3. [Bzoj4817] [Sdoi2017]树点涂色 (LCT神题)

    4817: [Sdoi2017]树点涂色 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 629  Solved: 371[Submit][Status ...

  4. bzoj4817 [Sdoi2017]树点涂色

    Description Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色. ...

  5. bzoj千题计划275:bzoj4817: [Sdoi2017]树点涂色

    http://www.lydsy.com/JudgeOnline/problem.php?id=4817 lct+线段树+dfs序 操作1:access 操作2:u到根的-v到根的-lca到根的*2+ ...

  6. BZOJ4817[Sdoi2017]树点涂色——LCT+线段树

    题目描述 Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色.Bob可能会进 ...

  7. BZOJ4817 [Sdoi2017]树点涂色 【LCT + 线段树】

    题目 Bob有一棵n个点的有根树,其中1号点是根节点.Bob在每个点上涂了颜色,并且每个点上的颜色不同.定义一条路 径的权值是:这条路径上的点(包括起点和终点)共有多少种不同的颜色.Bob可能会进行这 ...

  8. loj2001[SDOI2017]树点染色

    题意:给你一棵树,一开始每个点上的颜色互不相同.三种操作:op1:x到根的路径上的点都染上一种新的颜色.op2:设一条路径的权值为val(x,y),求x到y路径的val.op3:询问x的子树中最大的到 ...

  9. SDOI2017树点染色

    题目链接 发现1操作很像lct中的access,然后它每次染的又是一个新颜色,因此同一个颜色就在同一颗splay里了,且一个点到根的权值val[i]也就是到根路径上虚边的个数,然后看access时会对 ...

  10. 洛谷3703 [SDOI2017] 树点染色 【LCT】【线段树】

    题目分析: 操作一很明显等价于LCT上的access操作,操作二是常识,操作三转化到dfs序上求最大值也是常识.access的时候顺便在线段树中把对应部分-1,把右子树的子树+1即可. 代码: #in ...

随机推荐

  1. python-递归,二分查找

    # print(list("胡辣汤")) # lst = ["河南话", "四川话", "东北", "山东&q ...

  2. day20-正则表达式练习

    import re from re import findall,search,S secret_code = 'hadkfalifexxIxxfasdjifja134xxlovexx23345sdf ...

  3. CSS(三)--自定义标签

    HTML代码 <body> <ul> <li>1</li> <li>2</li> </ul> </body&g ...

  4. 【JAVA多线程】interrupted() 和 isInterrupted() 的区别

    Thread 类中提供了两种方法用来判断线程的状态是不是停止的.就是我们今天的两位主人公 interrupted() 和 isInterrupted() . interrupted() 官方解释:测试 ...

  5. Cracking The Coding Interview 9.1

    //原文: // // You are given two sorted arrays, A and B, and A has a large enough buffer at the end to ...

  6. Cracking The Coding Interview 3.6

    // Write a program to sort a stack in ascending order. You should not make any assumptions about how ...

  7. Win10安装mysql-8.0.11-winx64详细步骤

    安装 mysql-8.0.11-winx64 https://blog.csdn.net/qq_20788055/article/details/80372577

  8. 201621123001 《Java程序设计》第12周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 字节流以字节为基本处理单位,字符流以字符为基本处理单位,以Reader和Writer为基础派生出的一系列类 字 ...

  9. <Google><APAC><kickstart><2017.05.07><2017RoundB>

    Google APAC kickstart 网址链接 我的所有solution代码和文件请点击 前言 这个比赛的题怎一个变态了得,虽然是第一次参赛,抱着熟悉流程的心态去的,但仍然被虐得一颤一颤的╮(╯ ...

  10. ios手动添加数组字典(NSMutableDictionary)

    @property (nonatomic,strong) NSArray *imageData;//定义一个数组 -(NSArray *)imageDate { if(_imageDate==nil) ...