树链剖分样例过了TLE七个点为啥啊
查看原帖
树链剖分样例过了TLE七个点为啥啊
203102
Diamiko楼主2021/11/14 12:50
#include<bits/stdc++.h>
#define max(a,b) a>b?a:b
#define swap(a,b) a^=b^=a^=b
#define update(x) t[x]=t[x<<1]+t[x<<1|1]
using namespace std;
const int N=3e4+5;
vector<int>G[N];
int a[N];
int n,x,y,q;
string opt;
inline int read()
{
	int x(0);char c(0);bool flag(0);
	for(;!isdigit(c);c=getchar())if(c=='-')flag=1;
	for(;isdigit(c);c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	return flag?-x:x;
}
namespace Subdivision
{
	int fa[N],son[N],val[N],id[N],top[N],dep[N],siz[N],tot=0;
	void dfs1(int u,int father)
	{
		dep[u]=dep[father]+1;
		fa[u]=father;
		siz[u]=1;
		for(int v:G[u])
		{
			if(!dep[v]&&v!=father)
			{
				dfs1(v,u);
				siz[u]+=siz[v];
				if(siz[v]>siz[son[u]]) son[u]=v;
			}
		}
	}
	void dfs2(int u,int t)
	{
		top[u]=t;
		id[u]=++tot;
		val[tot]=a[u];
		if(!son[u])return;
		dfs2(son[u],t);
		for(int v:G[u])
		{
			if(v!=son[u]&&v!=fa[u])
			{
				dfs2(v,v);
			}
		}
	}
}
using namespace Subdivision;
namespace SegmentTree
{
	struct Node
	{
		int l,r,len,sum,maxx;
		Node operator +(Node x)
		{
			Node t;
			t={l,x.r,len+x.len,sum+x.sum,max(maxx,x.maxx)};
			return t;
		}
	}t[N<<2];
	void build(int now,int l,int r)
	{
		if(l==r)
		{
			t[now]={l,r,1,val[l],val[l]};
			return;
		}
		int mid=l+r>>1;
		build(now<<1,l,mid);
		build(now<<1|1,mid+1,r);
		update(now);
	}
	void modify(int now,int pos,int x)
	{
		if(t[now].l==t[now].r) 
		{
			t[now].sum=t[now].maxx=x;
			return;
		}
		int mid=t[now].l+t[now].r>>1;
		if(pos<=mid) modify(now<<1,pos,x);
		if(pos>mid)  modify(now<<1|1,pos,x);
		update(now);
	}
	Node query(int now,int x,int y)
	{
		if(t[now].l==t[now].r) return t[now];
		int mid=t[now].l+t[now].r>>1;
		if(x<=mid&&y>mid) return query(now<<1,x,y)+query(now<<1|1,x,y);
		if(x<=mid) return query(now<<1,x,y);
		if(y>mid)  return query(now<<1|1,x,y);
	}
}
inline int Qmax(int x,int y)
{
	int ans=-0x3f3f3f3f,tmp;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		tmp=SegmentTree::query(1,id[top[x]],id[x]).maxx;
		ans=max(ans,tmp);
		x=fa[top[x]];		
	}
	if(id[x]>id[y]) swap(x,y);
	tmp=SegmentTree::query(1,id[x],id[y]).maxx;
	ans=max(ans,tmp);
	return ans;
}
inline int Qsum(int x,int y)
{
	int ans=0;
	while(top[x]!=top[y])
	{
		if(dep[top[x]]<dep[top[y]]) swap(x,y);
		ans+=SegmentTree::query(1,id[top[x]],id[x]).sum;
		x=fa[top[x]];		
	}
	if(id[x]>id[y]) swap(x,y);
	ans+=SegmentTree::query(1,id[x],id[y]).sum;
	return ans;	
}
void write(int x)
{
	if(x<0) putchar('-'),x=-x;
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
int main()
{
//	freopen("count2.in","r",stdin);
//	freopen("tyk.out","w",stdout);
	n=read();
	for(int i=1;i<n;i++)
	{
		x=read();y=read();
		G[x].push_back(y);
		G[y].push_back(x);
	}
	for(int i=1;i<=n;i++) a[i]=read();
	dfs1(1,0);
	dfs2(1,1);
//	for(int i=1;i<=n;i++) cout<<val[id[i]]<<' ';
//	cout<<endl;
	SegmentTree::build(1,1,n);
	q=read();
	while(q--)
	{
		cin>>opt;
		x=read();y=read();
		if(opt=="CHANGE")
		{
			SegmentTree::modify(1,id[x],y);
		}
		else if(opt=="QMAX")
		{
			write(Qmax(x,y));
			putchar('\n');
		}
		else
		{
			write(Qsum(x,y));
			putchar('\n');
		}
	}
	return 0;
}
2021/11/14 12:50
加载中...