题解:CF893F Subtree Minimum Query

CF Luogu

见到强制在线,考虑用可持久化线段树维护。

假如以 dfs 序作为时间维,深度为第二维来可持久化,发现最小值不具有可减性,无法处理。

进而我们发现,一旦确定了 dfs 序的区间,那么只需要深度 \(\le k\) 即可,因为其祖先显然不在子树中,也就是说深度是一个前缀。所以考虑以深度为时间进行可持久化,然后查询 dfs 序区间最小值即可。

也可以以 dfs 序为 \(x\) 轴,深度为 \(y\) 轴,将其转化为二维数点,这样我们查询的矩形都是以 \(x\) 轴为下边界的,进而可以考虑按 \(y\) 值进行可持久化。

注意是 \(x=(x'+lastans)\mod n+1\) 而不是 \(x=(x'+lastans)\mod(n+1)\)

Code:

#include<iostream>
#include<vector>
#include<algorithm>
#define mid ((l+r)>>1)
#define rep(i,l,r) for(int i=(l);i<=(r);i++)
#define per(i,l,r) for(int i=(l);i>=(r);i--)
using namespace std;
const int maxn=1e5+5,inf=0x3f3f3f3f;
int a1[maxn],dep[maxn],dfn[maxn],siz[maxn],as[maxn],rt[maxn],tot,ndc;
struct node{
	int ls,rs,mn;
}at[maxn<<5];
vector<int> T[maxn];
inline void dfs(int cur,int fa){
	dep[cur]=dep[fa]+1;
	siz[cur]=1;
	dfn[cur]=++tot;
	for(int v:T[cur])if(v!=fa){
		dfs(v,cur);
		siz[cur]+=siz[v];
	}
}
inline bool cmp(int a,int b){
	return dep[a]<dep[b];
}
inline int clone(int x){
	at[++ndc]=at[x];
	return ndc;
}
inline int modify(int l,int r,int x,int pos,int v){
	x=clone(x);
	if(l==r){
		at[x].mn=min(at[x].mn,v);
		return x;
	}
	if(pos<=mid)at[x].ls=modify(l,mid,at[x].ls,pos,v);
	else at[x].rs=modify(mid+1,r,at[x].rs,pos,v);
	at[x].mn=min(at[at[x].ls].mn,at[at[x].rs].mn);
	return x;
}
inline int query(int l,int r,int x,int ql,int qr){
	if(!x)return inf;
	if(l>=ql&&r<=qr)return at[x].mn;
	int res=inf;
	if(ql<=mid)res=min(res,query(l,mid,at[x].ls,ql,qr));
	if(qr>mid)res=min(res,query(mid+1,r,at[x].rs,ql,qr));
	return res;
}
int main()
{
	int in,ir,im;
	cin>>in>>ir;
	rep(v1,1,in){
		scanf("%d",a1+v1);
		as[v1]=v1; 
	}
	rep(v1,1,in-1){
		int ix,iy;
		scanf("%d %d",&ix,&iy);
		T[ix].push_back(iy);
		T[iy].push_back(ix);
	}
	
	dfs(ir,0);
	sort(as+1,as+in+1,cmp);
	int cr=0;
	at[cr].mn=inf;
	rep(v1,1,in){
		cr=rt[dep[as[v1]]]=modify(1,in,cr,dfn[as[v1]],a1[as[v1]]);
	}
	
	scanf("%d",&im);
	int lastans=0;
	rep(v1,1,im){
		int ix,ik;
		scanf("%d %d",&ix,&ik);
		ix=(ix+lastans)%in+1;
		ik=(ik+lastans)%in;
		lastans=query(1,in,rt[min(dep[ix]+ik,dep[as[in]])],dfn[ix],dfn[ix]+siz[ix]-1);
		printf("%d\n",lastans);
	}
	return 0;
}
posted @ 2025-07-13 17:06  FugiPig  阅读(17)  评论(0)    收藏  举报