satt80分求助
  • 板块P5649 Sone1
  • 楼主zhengrunzhe
  • 当前回复7
  • 已保存回复7
  • 发布时间2020/6/1 20:53
  • 上次更新2023/11/7 01:18:30
查看原帖
satt80分求助
14374
zhengrunzhe楼主2020/6/1 20:53

回想起上一次攻坚这道题 已经是去年的十二月底 wa了#2#8 至今不知道为啥

#include<cstdio>
#include<cstddef>
#define int ll
template<class type>inline const void swap(type &a,type &b)
{
	const type c(a);a=b;b=c;
}
template<class type>inline const type min(const type &a,const type &b)
{
	return a<b?a:b;
}
template<class type>inline const type max(const type &a,const type &b)
{
	return a>b?a:b;
}
template<class type>inline const void read(type &in)
{
	in=0;char ch(getchar());bool f(0);
	while (ch<48||ch>57){if (ch=='-')f=1;ch=getchar();}
	while (ch>47&&ch<58)in=(in<<3)+(in<<1)+(ch&15),ch=getchar();
	if (f)in=-in;
}
typedef __int128 ll;
const int N(1e5+10);
namespace Self_Adjusting_Top_Trees
{
	const bool compress(0),rake(1);
	const int inf(2147483647);
	struct tree
	{
		bool rev;
		tree *son[3],*fa;
		static tree *null;
		int path_size,subtree_size,val;
		int path_add,subtree_add,path_cov,subtree_cov;
		int subtree_sum,path_sum,subtree_min,path_min,subtree_max,path_max;
		void *operator new(size_t size);
		void *operator new[](size_t size);
		void operator delete(void *ptr);
		inline tree():rev(0),val(0),subtree_size(0),path_size(0),path_add(0),subtree_add(0),path_sum(0),subtree_sum(0),path_min(inf),subtree_min(inf),path_cov(0),subtree_cov(0),subtree_max(-inf),path_max(-inf)
		{ 
			static bool init(0);
			if (!init)
			{
				init=1;
				null=new tree;
				null->son[0]=null->son[1]=null->son[2]=null->fa=null;
			}
			son[0]=son[1]=son[2]=fa=null;
		}
		inline const int identity()
		{
			for (int i(0);i<3;i++)if (fa->son[i]==this)return i;
			return 0;
		}
		inline const void set(tree *p,const int &f)
		{
			son[f]=p;p->fa=this;
		}
		inline const bool isroot()
		{
			return fa->son[0]!=this&&fa->son[1]!=this;
		}
		inline const void reverse()
		{
			if (this==null)return;swap(son[0],son[1]);rev^=1;
		}
		template<const bool type>inline const void pushup(){}
		template<const bool type>inline const void pushdown(){}
		template<const bool type>inline const void rotate()
		{
			const bool f(identity());
			fa->pushdown<type>();pushdown<type>();
			tree *fa(this->fa),*gfa(fa->fa),*q(son[f^1]);
			if (gfa!=null)gfa->son[fa->identity()]=this;
			(son[f^1]=fa)->son[f]=q;
			((q->fa=fa)->fa=this)->fa=gfa;
			fa->pushup<type>();pushup<type>();
		}
		template<const bool type>inline const void splay(tree *goal=null)
		{
			for (pushdown<type>();fa!=goal&&!isroot();rotate<type>())
				if (fa->fa!=goal&&!fa->isroot())
					fa->fa->pushdown<type>(),
					(fa->identity()^identity()?this:fa)->rotate<type>();
		}
		template<const bool type,const bool d>inline const void global_splay()
		{
			tree *p(this);
			for (;p->son[d]!=null;p=p->son[d])p->pushdown<type>();
			p->splay<type>(fa);
		}
		inline const void path_plus(const int &w)
		{
			if (this==null)return;
			val+=w;path_sum+=path_size*w;path_min+=w;path_max+=w;path_add+=w;
		}
		inline const void path_cover(const int &w)
		{
			if (this==null)return;
			val=w;path_sum=path_size*w;path_min=path_max=path_cov=w;path_add=0;
		}
		inline const void subtree_plus(const int &w)
		{
			if (this==null)return;
			subtree_sum+=subtree_size*w;subtree_min+=w;subtree_max+=w;subtree_add+=w;
		}
		inline const void subtree_cover(const int &w)
		{
			if (this==null)return;
			subtree_sum=subtree_size*w;subtree_min=subtree_max=subtree_cov=w;subtree_add=0;
		}
	}*root,*node0,*tree::null;
	#define null tree::null
	template<>inline const void tree::pushup<compress>()
	{
		path_size=son[0]->path_size+1+son[1]->path_size;
		subtree_size=son[0]->subtree_size+son[1]->subtree_size+son[2]->subtree_size;
		path_sum=son[0]->path_sum+val+son[1]->path_sum;
		path_min=min(val,min(son[0]->path_min,son[1]->path_min));
		path_max=max(val,max(son[0]->path_max,son[1]->path_max));
		subtree_sum=son[0]->subtree_sum+son[1]->subtree_sum+son[2]->subtree_sum;
		subtree_min=min(son[2]->subtree_min,min(son[0]->subtree_min,son[1]->subtree_min));
		subtree_max=max(son[2]->subtree_max,max(son[0]->subtree_max,son[1]->subtree_max));
	}
	template<>inline const void tree::pushup<rake>()
	{
		subtree_size=son[0]->subtree_size+son[1]->subtree_size+son[2]->path_size+son[2]->subtree_size;
		subtree_sum=son[0]->subtree_sum+son[1]->subtree_sum+son[2]->path_sum+son[2]->subtree_sum;
		subtree_min=min(min(son[0]->subtree_min,son[1]->subtree_min),min(son[2]->path_min,son[2]->subtree_min));
		subtree_max=max(max(son[0]->subtree_max,son[1]->subtree_max),max(son[2]->path_max,son[2]->subtree_max));
	}
	template<>inline const void tree::pushdown<compress>()
	{
		if (rev)son[0]->reverse(),son[1]->reverse(),rev=0;
		if (path_cov)son[0]->path_cover(path_cov),son[1]->path_cover(path_cov),path_cov=0;
		if (path_add)son[0]->path_plus(path_add),son[1]->path_plus(path_add),path_add=0;
		if (subtree_cov)son[0]->subtree_cover(subtree_cov),son[1]->subtree_cover(subtree_cov),son[2]->subtree_cover(subtree_cov),subtree_cov=0;
		if (subtree_add)son[0]->subtree_plus(subtree_add),son[1]->subtree_plus(subtree_add),son[2]->subtree_plus(subtree_add),subtree_add=0;
	}
	template<>inline const void tree::pushdown<rake>()
	{
		if (subtree_cov)
			son[0]->subtree_cover(subtree_cov),son[1]->subtree_cover(subtree_cov),
			son[2]->subtree_cover(subtree_cov),son[2]->path_cover(subtree_cov),subtree_cov=0;
		if (subtree_add)
			son[0]->subtree_plus(subtree_add),son[1]->subtree_plus(subtree_add),
			son[2]->subtree_plus(subtree_add),son[2]->path_plus(subtree_add),subtree_add=0;
	}
	const int maxn(N<<1);
	char memory_pool[maxn*sizeof(tree)],*tail=memory_pool+sizeof(memory_pool);
	void *recycle[maxn],**top=recycle;
	inline void *tree::operator new(size_t size){return top!=recycle?*--top:tail-=size;}
	inline void *tree::operator new[](size_t size){return tail-=size;}
	inline void tree::operator delete(void *ptr){*top++=ptr;}
	inline tree *node(const int &x){return node0+x;}
	inline const void splice(tree *p)
	{
		p->splay<rake>();
		p->fa->splay<compress>();p=p->fa;
		tree *q(p->son[2]);
		q->pushdown<rake>();
		if (p->son[1]!=null)
			swap(p->son[1]->fa,q->son[2]->fa),
			swap(p->son[1],q->son[2]);
		else
		{
			p->set(q->son[2],1);
			if (q->son[0]!=null)
				q->son[0]->global_splay<rake,1>(),
				q->son[0]->set(q->son[1],1),
				q->son[0]->pushup<rake>(),
				p->son[2]=q->son[0];
			else
				q->son[1]->pushdown<rake>(),
				p->son[2]=q->son[1];
			delete q;q=p->son[2];q->fa=p;
		}
		q->pushup<rake>();p->pushup<compress>();
		p->son[1]->rotate<compress>();
	}
	inline const void access(tree *p)
	{
		p->splay<compress>();
		if (p->son[1]!=null)
		{
			tree *q(new tree);
			q->set(p->son[2],0);
			q->set(p->son[1],2);
			q->pushup<rake>();
			p->son[1]=null;
			p->set(q,2);
			p->pushup<compress>();
		}
		while (p->fa!=null)splice(p->fa);
	}
	inline const void evert(tree *p)
	{
		access(p);p->reverse();
	}
	inline const void expose(tree *x,tree *y)
	{
		evert(x);access(y);
	}
	inline tree *findroot(tree *x)
	{
		for (access(x);x->son[0]!=null;x->pushdown<compress>())x=x->son[0];
		x->splay<compress>();
		return x;
	}
	inline const void link(tree *x,tree *y)
	{
		access(x);evert(y);x->set(y,1);x->pushup<compress>();
	}
	inline tree *cut(tree *x)
	{
		access(x);
		tree *fa=x->son[0];
		for (;fa->son[1]!=null;fa=fa->son[1])fa->pushdown<compress>();
		x->son[0]=x->son[0]->fa=null;
		x->pushup<compress>();
		return fa;
	}
	inline const void cover(tree *x,const int &y)
	{
		access(x);
		x->val=y;x->pushup<compress>();
		x->son[2]->subtree_cover(y);
	}
	inline const void makeroot(tree *x)
	{
		evert(root=x);
	}
	inline const void cover(tree *x,tree *y,const int &z)
	{
		expose(x,y);y->path_cover(z);evert(root);
	}
	inline const int query_min(tree *x)
	{
		access(x);return min(x->val,x->son[2]->subtree_min);
	}
	inline const int query_max(tree *x)
	{
		access(x);return max(x->val,x->son[2]->subtree_max);
	}
	inline const void add(tree *x,const int &y)
	{
		access(x);
		x->val+=y;x->pushup<compress>();
		x->son[2]->subtree_plus(y);
	}
	inline const int query_min(tree *x,tree *y)
	{
		expose(x,y);
		const int mn(y->path_min);
		evert(root);
		return mn;
	}
	inline const int query_max(tree *x,tree *y)
	{
		expose(x,y);
		const int mx(y->path_max);
		evert(root);
		return mx;
	}
	inline const void add(tree *x,tree *y,const int &z)
	{
		expose(x,y);y->path_plus(z);evert(root);
	}
	inline const void changefa(tree *x,tree *y)
	{
		if (x==y)return;
		tree *fa(cut(x));
		if (fa==null)return;
		if (findroot(x)==findroot(y))link(x,fa);
		else link(x,y);
		evert(root);
	}
	inline const int query_sum(tree *x,tree *y)
	{
		expose(x,y);
		const int sum(y->path_sum);
		evert(root);
		return sum;
	}
	inline const int query_sum(tree *x)
	{
		access(x);return x->son[2]->subtree_sum+x->val;
	}
}using namespace Self_Adjusting_Top_Trees;
int n,m,x[N],y[N];
signed main()
{
	read(n);read(m);
	node0=new tree[n+1];
	for (int i(1);i<n;i++)read(x[i]),read(y[i]);
	for (int i(1);i<=n;i++)read(node(i)->val),node(i)->pushup<compress>();
	for (int i(1);i<n;i++)link(node(x[i]),node(y[i]));
	int rt;read(rt);makeroot(node(rt));
	for (int opt,u,v,w;m--;)
		switch (read(opt),read(u),opt)
		{
			case 0:read(w);cover(node(u),w);break;
			case 1:makeroot(node(u));break;
			case 2:read(v);read(w);cover(node(u),node(v),w);break;
			case 3:printf("%d\n",query_min(node(u)));break;
			case 4:printf("%d\n",query_max(node(u)));break;
			case 5:read(w);add(node(u),w);break;
			case 6:read(v);read(w);add(node(u),node(v),w);break;
			case 7:read(v);printf("%d\n",query_min(node(u),node(v)));break;
			case 8:read(v);printf("%d\n",query_max(node(u),node(v)));break;
			case 9:read(v);changefa(node(u),node(v));break;
			case 10:read(v);printf("%d\n",query_sum(node(u),node(v)));break;
			case 11:printf("%d\n",query_sum(node(u)));break;
		}
	return 0;
}
2020/6/1 20:53
加载中...