版权声明: https://blog.csdn.net/DancingZ/article/details/82828185
Description
毛毛虫经过及时的变形,最终逃过的一劫,离开了菜妈的菜园。 毛毛虫经过千山万水,历尽千辛万苦,最后来到了小小的绍兴一中的校园里。爬啊爬~爬啊爬~~毛毛虫爬到了一颗小小的“毛景树”下面,发现树上长着他最爱吃的毛毛果~~~ “毛景树”上有N个节点和N-1条树枝,但节点上是没有毛毛果的,毛毛果都是长在树枝上的。但是这棵“毛景树”有着神奇的魔力,他能改变树枝上毛毛果的个数:
Change k w:将第k条树枝上毛毛果的个数改变为w个。
Cover u v w:将节点u与节点v之间的树枝上毛毛果的个数都改变为w个。
Add u v w:将节点u与节点v之间的树枝上毛毛果的个数都增加w个。
由于毛毛虫很贪,于是他会有如下询问:
Max u v:询问节点u与节点v之间树枝上毛毛果个数最多有多少个。
Input
第一行一个正整数N。
接下来N-1行,每行三个正整数Ui,Vi和Wi,第i+1行描述第i条树枝。表示第i条树枝连接节点Ui和节点Vi,树枝上有Wi个毛毛果。
接下来是操作和询问,以“Stop”结束。
Output
对于毛毛虫的每个询问操作,输出一个答案。
Sample Input
4
1 2 8
1 3 7
3 4 9
Max 2 4
Cover 2 4 5
Add 1 4 10
Change 1 16
Max 2 4
Stop
Sample Output
9 16
Hint
1<=N<=100,000,操作+询问数目不超过100,000。
保证在任意时刻,所有树枝上毛毛果的个数都不会超过10^9个。
据说是树剖的模板题,但是我觉得这个边操作树剖夹点有点不好搞,就换成lct吧。
维护的标记有点恶心~没有什么值得注意的地方。
ps:debug程序就不删了
#include<bits/stdc++.h>
using namespace std;
#define show_memory(x) cout<<sizeof(x)/(1024*1024*1.0)
const int Maxn=200005;
int n,l[Maxn],r[Maxn];
struct Splay{
int v[Maxn],mx[Maxn],cov[Maxn],tag[Maxn];
int p[Maxn],ch[2][Maxn];
bool rev[Maxn];
#define ls(x) ch[0][x]
#define rs(x) ch[1][x]
inline bool isroot(int x){
return (ls(p[x])^x)&&(rs(p[x])^x);
}
inline void maintain(int x){
mx[x]=v[x];
if(ls(x))mx[x]=max(mx[x],mx[ls(x)]);
if(rs(x))mx[x]=max(mx[x],mx[rs(x)]);
}
inline void rotate(int x){
int f=p[x],gf=p[f],tp=rs(f)==x,son=ch[!tp][x];
if(!isroot(f))ch[rs(gf)==f][gf]=x;p[x]=gf;
ch[tp][p[son]=f]=son,maintain(f);
ch[!tp][p[f]=x]=f,maintain(x);
}
inline void pushdown(int x){
if(rev[x]){
rev[ls(x)]^=1,rev[rs(x)]^=1;
swap(ls(x),rs(x));
rev[x]^=1;
}
if(cov[x]){
cov[ls(x)]=cov[rs(x)]=cov[x];
if(ls(x)>n)v[ls(x)]=cov[x];
if(rs(x)>n)v[rs(x)]=cov[x];
mx[ls(x)]=mx[rs(x)]=cov[x];
cov[x]=tag[ls(x)]=tag[rs(x)]=0;
}
if(tag[x]){
if(ls(x)>n)v[ls(x)]+=tag[x];
if(rs(x)>n)v[rs(x)]+=tag[x];
tag[ls(x)]+=tag[x];mx[ls(x)]+=tag[x];
tag[rs(x)]+=tag[x];mx[rs(x)]+=tag[x];
tag[x]=0;
}
}
int top,s[Maxn];
inline void splay(int x){
s[++top]=x;for(int i=x;!isroot(i);i=p[i])s[++top]=p[i];
while(top)pushdown(s[top--]);
while(!isroot(x)){
if(!isroot(p[x])&&((rs(p[p[x]])==p[x])==(rs(p[x])==x)))rotate(p[x]);
rotate(x);
}
}
inline void init(int x,int val){
p[x]=ls(x)=rs(x)=0;
v[x]=mx[x]=val;
}
/*
inline void debug(int x){
if(!x)return ;
pushdown(x);
debug(ls(x)),debug(rs(x));
maintain(x);
cout<<"idx: "<<x<<" lson:"<<ls(x)<<" rson:"<<rs(x)<<" val:"<<v[x]<<" Max:"<<mx[x]<<" add:"<<tag[x]<<" cov:"<<cov[x]<<"\n";
}
inline void print(){
for(int x=1;x<=n*2-1;++x){
cout<<"idx: "<<x<<" lson:"<<ls(x)<<" rson:"<<rs(x)<<" fa:"<<p[x]<<" val:"<<v[x]<<" Max:"<<mx[x]<<" add:"<<tag[x]<<" cov:"<<cov[x]<<"\n";
}
cout<<"\n";
}
*/
};
struct LinkCutTree{
Splay splay;
inline void access(int x){
for(int lastx=0;x;lastx=x,x=splay.p[x])
splay.splay(x),splay.rs(x)=lastx,splay.maintain(x);
}
inline void makeroot(int x){
access(x),splay.splay(x),splay.rev[x]^=1;
}
inline void link(int x,int y){
makeroot(x),splay.p[x]=y;
}
inline void split(int x,int y){
makeroot(x),access(y),splay.splay(y);
}
inline void cut(int x,int y){
split(x,y);splay.p[x]=splay.ls(y)=0;
splay.maintain(y);
}
inline void init(int x,int val){
splay.init(x,val);
}
}lct;
inline void getmax(){
int x,y;scanf("%d%d",&x,&y);
lct.split(x,y);
printf("%d\n",lct.splay.mx[y]);
}
inline void change(){
int x,k;scanf("%d%d",&x,&k);
lct.cut(l[x+n],x+n),lct.cut(r[x+n],x+n);
lct.init(x+n,k);
lct.link(x+n,l[x+n]),lct.link(x+n,r[x+n]);
// lct.splay.debug(r[x+n]);
}
inline void cover(){
int x,y,z;scanf("%d%d%d",&x,&y,&z);
lct.split(x,y);
lct.splay.cov[y]=lct.splay.mx[y]=z;
lct.splay.tag[y]=0;
// lct.splay.debug(y);
}
inline void add(){
int x,y,z;scanf("%d%d%d",&x,&y,&z);
lct.split(x,y);
lct.splay.tag[y]+=z;
lct.splay.mx[y]+=z;
// lct.splay.debug(y);
}
int main(){
scanf("%d",&n);
for(int i=1;i<n;++i){
int x,y,z;scanf("%d%d%d",&x,&y,&z);
lct.init(n+i,z);
l[n+i]=x,r[n+i]=y;
lct.link(n+i,x),lct.link(n+i,y);
}
while("I'm too handsome~ ~"){
char op[23];scanf("%s",op+1);
if(op[1]=='S')break;
if(op[2]=='a')getmax();
if(op[2]=='h')change();
if(op[2]=='o')cover();
if(op[2]=='d')add();
}
/*
for(int i=1;i<=n*2-1;++i)
cout<<lct.splay.v[i]<<" ";
*/
return 0;
}