树链剖分求调
查看原帖
树链剖分求调
199459
Masna_Kimoyo楼主2021/12/4 19:26

求一个好心人qwq

代码:

#include<bits/stdc++.h>
#define printlf(x) print(x),putchar('\n')
#define printsp(x) print(x),putchar(' ')
using namespace std;
const int N=1e5+5;
inline int read(){
	int x=0;
	bool w=0;
	char c=getchar();
	while(!isdigit(c))  w|=c=='-',c=getchar();
	while(isdigit(c))   x=(x<<1)+(x<<3)+(c^48),c=getchar();
	return w?-x:x;
}
inline void print(int x){
	if(x<0) x=-x,putchar('-');
	if(x>9) print(x/10);
	putchar('0'+x%10);
}
struct node{
	int to,next,dis;
}Edge[N<<1];
int n,tot;
int head[N];
inline void add(int u,int v,int w){
	Edge[++tot].to=v;
	Edge[tot].next=head[u];
	Edge[tot].dis=w;
	head[u]=tot;
}
namespace TSC{
	int maxx[N<<2],tagp[N<<2],tagu[N<<2],fa[N],dep[N],siz[N],id[N],a[N],son[N],top[N];
	int cnt;
#define ls(x) x<<1
#define rs(x) x<<1|1
#define push_up(p) maxx[p]=max(maxx[ls(p)],maxx[rs(p)])
	inline void change1(int p,int l,int r,int k){
		tagp[p]=0;
		maxx[p]=k;
	}
	inline void change2(int p,int l,int r,int k){
		tagp[p]+=k;
		maxx[p]+=k;	
	}
	inline void push_down(int p,int l,int r){
		int mid=(l+r)>>1;
		if(~tagu[p]){
			change1(ls(p),l,mid,tagu[p]);
			change1(rs(p),mid+1,r,tagu[p]);
			tagu[p]=-1;
		}	
		if(tagp[p]){
			change2(ls(p),l,mid,tagp[p]);
			change2(rs(p),mid+1,r,tagp[p]);
			tagp[p]=0;	
		}
	}
	inline void Build(int p,int l,int r){
		tagu[p]=-1;
		if(l==r){
			maxx[p]=a[l];
			// printf("l:%d maxx:%d\n",p,maxx[p]);
			return ;
		}
		int mid=(l+r)>>1;
		Build(ls(p),l,mid);
		Build(rs(p),mid+1,r);
		push_up(p);
	}
	inline void Update(int p,int l,int r,int pl,int pr,int k,int d){
		if(l>pr || r<pl)	return ;
		if(l>=pl && r<=pr){
			if(!d)	change1(p,l,r,k);
			else	change2(p,l,r,k);
			return ;
		}
		push_down(p,l,r);
		int mid=(l+r)>>1;
		if(mid>=pl)	Update(ls(p),l,mid,pl,pr,k,d);
		if(mid<pr)	Update(rs(p),mid+1,r,pl,pr,k,d);
		push_up(p);
	}
	inline int Query(int p,int l,int r,int pl,int pr){
		if(l>pr || r<pl)	return 0;
		if(l>=pl && r<=pr)	return maxx[p];
		push_down(p,l,r);
		int mid=(l+r)>>1,res=0;
		if(mid>=pl)	res=max(res,Query(ls(p),l,mid,pl,pr));
		if(mid<pr)	res=max(res,Query(rs(p),mid+1,r,pl,pr));
		return res;
	}
	inline void dfs1(int x,int f){
		dep[x]=dep[f]+1;
		fa[x]=f;
		siz[x]=1;
		int maxsiz=0;
		for(register int i=head[x];i;i=Edge[i].next){
			int v=Edge[i].to,w=Edge[i].dis;
			// printf("dis:%d\n",w);
			if(v==f)	continue;
			dfs1(v,x);
			siz[x]+=siz[v];
			a[v]=w;
			if(siz[v]>maxsiz)	maxsiz=siz[v],son[x]=v;
		}
	}
	inline void dfs2(int x,int topx){
		id[x]=++cnt;
		top[x]=topx;
		if(!son[x])	return ;
		dfs2(son[x],topx);
		for(register int i=head[x];i;i=Edge[i].next){
			int v=Edge[i].to;
			if(v==fa[x] || v==son[x])	continue;
			dfs2(v,v);
		}		
	}
	inline void Lupdate(int x,int y,int k,int d){
		while(top[x]!=top[y]){
			if(dep[top[x]]<dep[top[y]])	swap(x,y);
			Update(1,1,n,id[top[x]],id[x],k,d);
			x=fa[top[x]];
		}		
		if(dep[x]>dep[y])	swap(x,y);
		Update(1,1,n,id[x]+1,id[y],k,d);
	}
	inline int Lquery(int x,int y){
		int res=0;
		while(top[x]!=top[y]){
			if(dep[top[x]]<dep[top[y]])	swap(x,y);
			res=max(res,Query(1,1,n,id[top[x]],id[x]));
			x=fa[top[x]];
		}
		if(dep[x]>dep[y])	swap(x,y);
		return max(res,Query(1,1,n,id[x]+1,id[y]));
	}
}
using namespace TSC;
inline void work1(){
	int x=read(),k=read();
	if(dep[Edge[x*2-1].to]<dep[Edge[x<<1].to])	Update(1,1,n,id[Edge[x<<1].to],id[Edge[x<<1].to],k,0);
	if(dep[Edge[x*2-1].to]>dep[Edge[x<<1].to])	Update(1,1,n,id[Edge[x*2-1].to],id[Edge[x*2-1].to],k,0);
}
inline void work2(){
	int x=read(),y=read(),k=read();
	Lupdate(x,y,k,0);
}
inline void work3(){
	int x=read(),y=read(),k=read();
	Lupdate(x,y,k,1);
}
inline void work4(){
	int x=read(),y=read();
	printlf(Lquery(x,y));
}
signed main(){
	n=read();
	for(register int i=1;i<n;++i){
		int u=read(),v=read(),w=read();
		add(u,v,w),add(v,u,w);
	}
	dfs1(1,0),dfs2(1,1),Build(1,1,n);
	// for(register int i=1;i<=n;++i)	printsp(siz[i]);puts("");
	// for(register int i=1;i<=n;++i)	printsp(id[i]);puts("");
	// for(register int i=1;i<=n;++i)	printsp(a[i]);puts("");
	string s;
	while(cin>>s){
		if(s[0]=='S')	return 0;
		if(s[0]=='C' && s[1]=='h')	work1();
		if(s[0]=='C' && s[1]=='o')	work2();
		if(s[0]=='A')	work3();
		if(s[0]=='M')	work4();
	}
	return 0;
}
2021/12/4 19:26
加载中...