树剖+线段树动态开点求条
查看原帖
树剖+线段树动态开点求条
826774
Little_Fox_Fairy楼主2024/7/11 11:04
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#define int long long
using namespace std;
const int N=1e5+10;
char eof_flag;inline char read(int*s){if(eof_flag)return 0;int k=0,f=1;char c=getchar();while(c!='-'&&(c<'0'||c>'9')){if(c==EOF){eof_flag=1;return 0;}c=getchar();}f=(c=='-')?-1:1;k=(c=='-')?0:(c^48);c=getchar();while(c>='0'&&c<='9')k=(k<<1)+(k<<3)+(c^48),c=getchar();if(c==EOF)eof_flag=1;(*s)=f>0?k:-k;return 1;}
inline void write(int x){if(x<0)putchar('-'),x=-x;if(x>9)write(x/10);putchar(x%10+'0');return;}

int n,q;
int size[N],dep[N],f[N],top[N],son[N],idx[N],seq[N],cnt,s[N],col[N];
int tot,root[N];
vector<int> e[N];
struct node {int l,r,maxx,sum;}t[N*40];
inline void push_up(int u)
{
	t[u].sum=t[t[u].l].sum+t[t[u].r].sum;
	t[u].maxx=max(t[t[u].l].maxx,t[t[u].r].maxx);
	return ;
}
inline void update(int &u,int l,int r,int pos,int w)
{
	if (!u) u=++tot;
	if (l==r)
	{
		t[u].sum=t[u].maxx=w;
		return ;
	}
	int mid=l+r>>1;
	if (pos<=mid) update(t[u].l,l,mid,pos,w);
	else update(t[u].r,mid+1,r,pos,w);
	push_up(u);
	return ;
}
inline int query_max(int u,int l,int r,int L,int R)
{
	if (!u) return -1;
	if (r<L or l>R) return -1;
	if (l>=L and r<=R) return t[u].maxx;
	int mid=l+r>>1;
	return max(query_max(t[u].l,l,mid,L,R),query_max(t[u].r,mid+1,r,L,R));
}
inline int query_sum(int u,int l,int r,int L,int R)
{
	if (!u) return 0;
	if (r<L or l>R) return 0;
	if (l>=L and r<=R) return t[u].sum;
	int mid=l+r>>1;
	return query_sum(t[u].l,l,mid,L,R)+query_sum(t[u].r,mid+1,r,L,R);
}
inline void dfs(int u,int fa)
{
	dep[u]=dep[fa]+1,f[u]=fa;
	size[u]=1;
	for (auto v : e[u])
	{
		if (v==fa) continue;
		dfs(v,u);
		if (size[v]>size[son[u]]) son[u]=v;
	}
	return ;
}
inline void df5(int u,int topfa)
{
	idx[u]=++cnt,seq[cnt]=u;
	top[u]=topfa;
	if (son[u]) df5(son[u],topfa);
	for (auto v : e[u])
	{
		if (v==f[u] or v==son[u]) continue;
		df5(v,v);
	}
	return ;
}
inline int query_range_max(int u,int v)
{
	int ans=-1,tmp=col[v];
	while (top[u]!=top[v])
	{
		if (dep[top[u]]<dep[top[v]]) swap(u,v);
		ans=max(ans,query_max(root[tmp],1,n,idx[top[u]],idx[u]));
		u=f[top[u]];
	}
	if (dep[u]<dep[v]) swap(u,v);
	ans=max(ans,query_max(root[tmp],1,n,idx[v],idx[u]));
	return ans;
}
inline int query_range_sum(int u,int v)
{
	int ans=0,tmp=col[v];
	while (top[u]!=top[v])
	{
		if (dep[top[u]]<dep[top[v]]) swap(u,v);
		ans+=query_sum(root[tmp],1,n,idx[top[u]],idx[u]);
		u=f[top[u]];
	}
	if (dep[u]<dep[v]) swap(u,v);
	ans+=query_sum(root[tmp],1,n,idx[v],idx[u]);
	return ans;
}
signed main()
{
	ios::sync_with_stdio(0);
	cin>>n>>q;
	for (int i=1;i<=n;i++) cin>>s[i]>>col[i];
	for (int i=1;i<=n-1;i++)
	{
		int u,v;
		cin>>u>>v;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	dfs(1,0),df5(1,1);
//	update(root[col[seq[1]]],1,n,1,s[seq[1]]);
	for (int i=1;i<=n;i++) update(root[col[seq[i]]],1,n,i,s[seq[i]]);
	while (q--)
	{
		string t;
		int u,v;
		cin>>t;
		cin>>u>>v;
//		cout<<t<<" "<<u<<" "<<v<<endl;
		if (t=="CC")
		{
			update(root[col[u]],1,n,idx[u],0);
			col[u]=v;
			update(root[col[u]],1,n,idx[u],t[u]);
		}
		if (t=="CW") t[u]=v,update(root[col[u]],1,n,idx[u],v);
		if (t=="QS") cout<<query_range_max(u,v)<<endl;
		if (t=="QM") cout<<query_range_sum(u,v)<<endl;
	}
	return 0;
}

没过样例。。。

2024/7/11 11:04
加载中...