30pts点分治求调
查看原帖
30pts点分治求调
713562
hahaxiang楼主2024/7/12 16:11
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e4+10;
int oldn,n,q,g[N],s[N],cnt,col[N],ans[N*10];
bool vis[N];
vector<int>edge[N];
struct query{
	int l,r,id;
}Q[N*200];
vector<query>lft[N];
struct basis{
	int a[70];
	void add(int x)
	{
		for(int i=60;i>=0;i--)
		{
			if((x&(1ll<<i))!=0)
			{
				if(a[i]==0)
				{
					a[i]=x;
					break;
				}
				else
				{
					x^=a[i];
				}
			}
		}
	}
	int get()
	{
		int s=0;
		for(int i=60;i>=0;i--)
		{
			s=max(s,s^a[i]);
		}
		return s;
	}
	void clear()
	{
		memset(a,0,sizeof(a));
		return;
	}
}nw,a[N];
basis merge(basis x,basis y)
{
	for(int i=60;i>=0;i--)
	{
		x.add(y.a[i]);
	}
	return x;
}
void dfs2(int x,int fa,int c)
{
	col[x]=c;
	nw.add(g[x]);
	a[x]=nw;
	for(int i=0;i<edge[x].size();i++)
	{
		int to=edge[x][i];
		if(to==fa||vis[to]==1)
		continue;
		dfs2(to,x,c);
	}
	return;
}
void solve(int x,int L,int R)
{
	col[x]=0;
	nw.clear();
	nw.add(g[x]);
	a[x]=nw;
	for(int i=0;i<edge[x].size();i++)
	{
		int to=edge[x][i];
		if(vis[to]==1)
		continue;
		nw.clear();
		nw.add(g[x]);
		dfs2(to,x,i+1);
		lft[i+1].clear();
	}
	for(int i=L;i<=R;i++)
	{
		if(col[Q[i].l]!=col[Q[i].r]||col[Q[i].l]==0)
		{
			ans[Q[i].id]=merge(a[Q[i].l],a[Q[i].r]).get();
		}
		else
		{
			lft[col[Q[i].l]].push_back(Q[i]);
		}
	}
	return;
}
bool dfs(int x,int fa,int L,int R)
{
	s[x]=1;
	int mx=0;
	for(int i=0;i<edge[x].size();i++)
	{
		int to=edge[x][i];
		if(to==fa||vis[to]==1)
		continue;
		if(dfs(to,x,L,R)==1)
		return 1;
		s[x]+=s[to];
		mx=max(mx,s[to]);
	}
	mx=max(mx,n-s[x]);
	if(mx<=n/2)
	{
		vis[x]=1;
		s[fa]=n-s[x];
		solve(x,L,R);
		vector<int>v,LL;
		for(int i=0;i<edge[x].size();i++)
		{
			int to=edge[x][i];
			if(vis[to]==1)
			continue;
			v.push_back(lft[i+1].size());
			if(lft[i+1].size()!=0)
			LL.push_back(cnt+1);
			else
			LL.push_back(0); 
			for(int j=0;j<lft[i+1].size();j++)
			{
				cnt++;
				Q[cnt]=lft[i+1][j];
			}
		}
		for(int i=edge[x].size()-1;i>=0;i--)
		{
			int to=edge[x][i];
			if(vis[to]==1)
			continue;
			if(v[v.size()-1]==0)
			{
				v.pop_back();
				LL.pop_back();
				continue;
			}
			n=s[to];
			dfs(to,x,LL[LL.size()-1],LL[LL.size()-1]+v[v.size()-1]-1);
			v.pop_back();
			LL.pop_back();
		}
		return 1;
	}
	return 0;
} 
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
//	freopen("P3292_1.in","r",stdin);
	cin>>n>>q;
	oldn=n;
	for(int i=1;i<=n;i++)
	{
		cin>>g[i];
	}
	for(int i=1;i<n;i++)
	{
		int u,v;
		cin>>u>>v;
		edge[u].push_back(v);
		edge[v].push_back(u);
	}
	for(int i=1;i<=q;i++)
	{
		cin>>Q[i].l>>Q[i].r;
		Q[i].id=i;
	}
	cnt=q;
	dfs(1,0,1,q);
	for(int i=1;i<=q;i++)
	{
		cout<<ans[i]<<'\n';
	}
	return 0;
}
2024/7/12 16:11
加载中...