萌新刚学树链剖分,0分求调
查看原帖
萌新刚学树链剖分,0分求调
553625
scp020楼主2024/1/22 22:46
#include<bits/stdc++.h>
namespace fast_IO
{
	#define Getchar() p1==p2 and (p2=(p1=Inf)+fread(Inf,1,1<<21,stdin),p1==p2)?EOF:*p1++
	#define Putchar(c) p3==p4 and (fwrite(Ouf,1,1<<21,stdout),p3=Ouf),*p3++=c
	char Inf[1<<21],Ouf[1<<21],*p1,*p2,*p3=Ouf,*p4=Ouf+(1<<21);
	inline void read(int &x,char c=Getchar())
	{
		bool f=c!=45;
		x=0;
		while(c<48 or c>57) c=Getchar(),f&=c!=45;
		while(c>=48 and c<=57) x=(x<<3)+(x<<1)+(c^48),c=Getchar();
		x=f?x:-x;
	}
	inline void write(int x)
	{
		if(x<0) Putchar(45),x=-x;
		if(x>=10) write(x/10),x%=10;
		Putchar(x^48);
	}
	inline void read(short &x,char c=Getchar())
	{
		bool f=c!=45;
		x=0;
		while(c<48 or c>57) c=Getchar(),f&=c!=45;
		while(c>=48 and c<=57) x=(x<<3)+(x<<1)+(c^48),c=Getchar();
		x=f?x:-x;
	}
	inline void write(short x)
	{
		if(x<0) Putchar(45),x=-x;
		if(x>=10) write(x/10),x%=10;
		Putchar(x^48);
	}
	inline void read(long long &x,char c=Getchar())
	{
		bool f=c!=45;
		x=0;
		while(c<48 or c>57) c=Getchar(),f&=c!=45;
		while(c>=48 and c<=57) x=(x<<3)+(x<<1)+(c^48),c=Getchar();
		x=f?x:-x;
	}
	inline void write(long long x)
	{
		if(x<0) Putchar(45),x=-x;
		if(x>=10) write(x/10),x%=10;
		Putchar(x^48);
	}
	inline bool inrange(const char &ch)
	{
		if(ch>=33 && ch<=126) return true;
		return false;
	}
	inline void read(std::string &st,char c=Getchar())
	{
		st.clear();
		while(!inrange(c)) c=Getchar();
		while(inrange(c)) st+=c,c=Getchar();
	}
	inline void write(std::string st)
	{
		for(int i=0;i<st.size();i++) Putchar(st[i]);
	}
	inline void read(char &ch)
	{
		ch=Getchar();
		while(!inrange(ch)) ch=Getchar();
	}
	inline void write(const char &ch)
	{
		Putchar(ch);
	}
	class fastin
	{
	public:
		template<typename T>
		inline fastin &operator>>(T &x)
		{
			read(x);
			return *this;
		}
	};
	class fastout
	{
	public:
		template<typename T>
		inline fastout &operator<<(T x)
		{
			write(x);
			return *this;
		}
	};
	fastin in;
	fastout out;
};
using namespace fast_IO;
int n,dep[100010],f[100010],siz[100010],hvson[100010],bel[100010],tot,neww[100010],w[100010],start[100010];
struct edge
{
	int to,cost;
	edge *next;
};
edge *head[100010];
inline void add(const int &x,const int &y,const int &z)
{
	edge *e=new edge;
	e->to=y,e->next=head[x],e->cost=z,head[x]=e;
}
inline void dfs1(int pos,int fa,int depth,int maxi=-0x3f3f3f3f)
{
	dep[pos]=depth,f[pos]=fa,siz[pos]=1;
	for(edge *i=head[pos];i;i=i->next)
	{
		if(i->to!=fa)
		{
			dfs1(i->to,pos,depth+1),w[i->to]=i->cost,siz[pos]+=siz[i->to];
			if(siz[i->to]>maxi) hvson[pos]=i->to,maxi=siz[i->to];
		}
	}
}
inline void dfs2(int pos,int Start)
{
	bel[pos]=++tot,neww[tot]=w[pos],start[pos]=Start;
	if(hvson[pos])
	{
		dfs2(hvson[pos],Start);
		for(edge *i=head[pos];i;i=i->next)
			if(i->to!=f[pos] && i->to!=hvson[pos]) dfs2(i->to,i->to);
	}
}
struct node
{
	int sum,lazy1,lazy2; // lazy1 是区间推平,lazy2 是区间加
	node *lc,*rc;
	inline node()
	{
		sum=lazy2=0,lazy1=0x3f3f3f3f,lc=rc=nullptr;
	}
	inline void pushup()
	{
		sum=std::max(lc->sum,rc->sum);
	}
	inline void pushdown()
	{
		if(lazy1!=0x3f3f3f3f)
		{
			lc->sum=rc->sum=lc->lazy1=rc->lazy1=lazy1,lc->lazy2=rc->lazy2=0;
			lazy1=0x3f3f3f3f;
		}
		if(lazy2)
		{
			lc->sum+=lazy2,rc->sum+=lazy2,lc->lazy2+=lazy2,rc->lazy2+=lazy2;
			lazy2=0;
		}
	}
};
class seg_tree
{
	#define ls l,mid
	#define rs mid+1,r
private:
	node *root;
	inline node *build(int l,int r)
	{
		node *rt=new node();
		if(l==r) rt->sum=neww[l];
		else
		{
			int mid=(l+r)/2;
			rt->lc=build(ls),rt->rc=build(rs),rt->pushup();
		}
		return rt;
	}
	inline void fix1(node *rt,const int &L,const int &R,const int &val,int l,int r)
	{
		if(L<=l && r<=R)
		{
			rt->lazy1=val,rt->lazy2=0,rt->sum=val;
			return;
		}
		int mid=(l+r)/2;
		rt->pushdown();
		if(L<=mid) fix1(rt->lc,L,R,val,ls);
		if(R>mid) fix1(rt->rc,L,R,val,rs);
		rt->pushup();
	}
	inline void fix2(node *rt,const int &L,const int &R,const int &val,int l,int r)
	{
		if(L<=l && r<=R)
		{
			rt->lazy2+=val,rt->sum+=val;
			return;
		}
		int mid=(l+r)/2;
		rt->pushdown();
		if(L<=mid) fix2(rt->lc,L,R,val,ls);
		if(R>mid) fix2(rt->rc,L,R,val,rs);
		rt->pushup();
	}
	inline int ask(node *rt,const int &L,const int &R,int l,int r)
	{
		if(L<=l && r<=R) return rt->sum;
		int mid=(l+r)/2,ret=0;
		rt->pushdown();
		if(L<=mid) ret=std::max(ret,ask(rt->lc,L,R,ls));
		if(R>mid) ret=std::max(ret,ask(rt->rc,L,R,rs));
		return ret;
	}
public:
	inline void build()
	{
		root=build(1,n);
	}
	inline void fix1(const int &L,const int &R,const int &val)
	{
		fix1(root,L,R,val,1,n);
	}
	inline void fix2(const int &L,const int &R,const int &val)
	{
		fix2(root,L,R,val,1,n);
	}
	inline int ask(const int &L,const int &R)
	{
		return ask(root,L,R,1,n);
	}
};
seg_tree tree;
inline int ask(int x,int y)
{
	int ret=0;
	while(start[x]!=start[y])
	{
		if(dep[start[x]]<dep[start[y]]) std::swap(x,y);
		ret=std::max(ret,tree.ask(bel[start[x]],bel[x])),x=f[start[x]];
	}
	if(dep[x]>dep[y]) std::swap(x,y);
	return std::max(ret,tree.ask(bel[x],bel[y]));
}
inline void fix1(int x,int y,const int &z)
{
	while(start[x]!=start[y])
	{
		if(dep[start[x]]<dep[start[y]]) std::swap(x,y);
		tree.fix1(bel[start[x]],bel[x],z),x=f[start[x]];
	}
	if(dep[x]>dep[y]) std::swap(x,y);
	tree.fix1(bel[x],bel[y],z);
}
inline void fix2(int x,int y,const int &z)
{
	while(start[x]!=start[y])
	{
		if(dep[start[x]]<dep[start[y]]) std::swap(x,y);
		tree.fix2(bel[start[x]],bel[x],z),x=f[start[x]];
	}
	if(dep[x]>dep[y]) std::swap(x,y);
	tree.fix2(bel[x],bel[y],z);
}
std::string op;
std::pair<int,int> p[100010];
inline void fileIO(std::string filename)
{
	std::string I=filename+".in",O=filename+".out";
	freopen(I.c_str(),"r",stdin);
	freopen(O.c_str(),"w",stdout);
}
signed main()
{
// 	fileIO("P4315_1");
	in>>n;
	for(int i=1,x,y,z;i<n;i++) in>>x>>y>>z,p[i].first=x,p[i].second=y,add(x,y,z),add(y,x,z);
	dfs1(1,0,1),dfs2(1,1),tree.build();
	int x,y,z;
	while(1)
	{
		in>>op;
		if(op=="Stop") break;
		if(op=="Change") in>>x>>y,fix1(p[x].first,p[x].second,y);
		else if(op=="Cover") in>>x>>y>>z,fix1(x,y,z);
		else if(op=="Add") in>>x>>y>>z,fix2(x,y,z);
		else in>>x>>y,out<<ask(x,y)<<'\n';
	}
	fwrite(Ouf,1,p3-Ouf,stdout),fflush(stdout);
	return 0;
}
2024/1/22 22:46
加载中...