25MX集训0801

T2不会

T1:

考虑点分治,把所有询问挂在分支中心

对于每一个 \(u\) 维护 \(dpU_{u,k,j}\) 表示最大值为 \(k\) ,最小值为 \(j\) 的从 \(u\) 到分支中心的最长不降子序列

同理维护 \(dpD_{u,k,j}\) 表示最大值为 \(k\) ,最小值为 \(j\) 的从 \(u\) 到分支中心的最长不升子序列

对于每一个询问求得 $ max~~{dpU_{x,i,1}+dpD_{y,k,i}} $ 即可

代码:

点击查看代码
#include<bits/stdc++.h>
using namespace std;
using ll=long long;
#define int ll
const int N=1e5+5,K=11,Q=3e6+5;

int n,q,k;
int dpu[N][K][K],dpd[N][K][K];
int rt,siz[N],tot,mxp[N];
int fth[N][18],dep[N];
bool vis[N];
vector<pair<int,int>> G[N];
struct node
{
	int x,y,pos;
};
vector<node> Que[N];
int ans[Q];

void dfs(int u,int fa)
{
	fth[u][0]=fa,dep[u]=dep[fa]+1;
	for(int i=1;i<=17;i++)
		fth[u][i]=fth[fth[u][i-1]][i-1];
	for(auto [v,_]:G[u])
		if(v!=fa) dfs(v,u);
}

int lca(int x,int y)
{
	if(dep[x]<dep[y]) swap(x,y);
	for(int i=17;i>=0;i--)
		if(dep[fth[x][i]]>=dep[y])
			x=fth[x][i];
//	cerr<<x<<" "<<y<<'\n';
	if(x==y) return x;
	for(int i=17;i>=0;i--)
	{
		if(fth[x][i]!=fth[y][i])
		{
			x=fth[x][i];
			y=fth[y][i];
		}
	}
	return fth[x][0];
}

void dfs1(int u,int fa)
{
	siz[u]=1,mxp[u]=0;
	for(auto [v,w]:G[u])
	{
		if(v==fa||vis[v]) continue;
		dfs1(v,u);
		siz[u]+=siz[v];
		mxp[u]=max(siz[v],mxp[u]);
	}
	mxp[u]=max(mxp[u],tot-siz[u]);
	if(mxp[u]<mxp[rt]) rt=u;
}

void clac(int u,int fa,int w)
{
	for(int j=1;j<K;j++)
		for(int i=j;i<K;i++)
			dpu[u][j][i]=max(dpu[fa][j][i]+(i==w),dpu[u][j][i-1]);
	for(int j=K-1;j;j--)
		for(int i=j;i;i--)
			dpd[u][j][i]=max(dpd[fa][j][i]+(i==w),dpd[u][j][i+1]);
	return ;
}

void dfs2(int u,int fa)
{
	for(auto [v,w]:G[u])
	{
		if(v==fa||vis[u]) continue;
		clac(v,u,w);
		dfs2(v,u);
	}
	return ;
}

void update(int u)
{
	for(int i=1;i<K;i++) 
		for(int j=1;j<K;j++)
			dpu[u][i][j]=dpd[u][i][j]=0;
	for(auto [v,w]:G[u])
	{
		if(vis[v]) continue;
		clac(v,u,w);
		dfs2(v,u);
	}
//	cout<<"RT:"<<rt<<'\n';
	for(auto [x,y,pos]:Que[u])
	{
		int mx=0;
//		cerr<<"now: "<<x<<" "<<y<<'\n';
		for(int i=1;i<K;i++)
		{
//			cerr<<i<<"  U:"<<dpd[x][i][1]<<" D:"<<dpu[y][i][K-1]<<'\n';
			mx=max(mx,dpd[x][i][1]+dpu[y][i][K-1]);
		}
		ans[pos]=mx;
	}
	Que[u].clear();
	return ;
}

void solve(int u)
{
	vis[u]=1,update(u);
	for(auto [v,_]:G[u])
	{
		if(vis[v]) continue;
		tot=siz[v],mxp[rt=0]=1e9;
		dfs1(v,0),solve(rt);
	}
}

void solve();

signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);cout.tie(0);
	freopen("maze.in","r",stdin);
	freopen("maze.out","w",stdout);
	int c,_=1;
	cin>>c;
	while(_--) solve();
	return 0;
}

void solve()
{
	cin>>n>>q>>k;
	for(int i=1;i<n;i++)
	{
		int u,v,w;
		cin>>u>>v>>w;
		G[u].push_back({v,w});
		G[v].push_back({u,w});
	}
	mxp[rt=0]=n,tot=n,dfs1(1,0);
//	cerr<<rt<<'\n';
	dfs(rt,rt);
	int x,y,a,b,c;
	cin>>x>>y>>a>>b>>c;
	for(int i=1;i<=q;i++)
	{
		int nx,ny;
//		cin>>x>>y;nx=x,ny=y;
		nx=(x*a+(ll)y*y*b+c+(ll)i*i)%n+1;
		ny=((ll)x*x*a+y*b+(ll)c*c+i)%n+1;
		int z=lca(nx,ny);
//		cerr<<nx<<" "<<ny<<" "<<z<<'\n';
		Que[z].push_back({nx,ny,i});
		x=nx,y=ny;
	}
	solve(rt);
	ll res=0;
	for(int i=1;i<=q;i++) 
	{
//		cerr<<ans[i]<<" ";
		res^=(ll)i*ans[i];
	}
//	cerr<<'\n';
	cout<<res;
	for(int i=1;i<=n;i++) G[i].clear();
	return ;
}

posted @ 2025-08-01 21:26  Sgt_Dante  阅读(2)  评论(0)    收藏  举报