「题解」:$e$
问题 B: $e$
时间限制: 2 Sec 内存限制: 512 MB
题面
题面谢绝公开。
题解
话说一天考两个主席树这回事……
正解可以叫树上主席树??(脸哥说也叫主席树上树???)
对于树上的每一条链建主席树,支持链上查询前驱和后继。
对于所有的$p[i]$,他说怎么得到就按他说的做就好,然后求所有$p[i]$的$LCA$。
对于每个$p[i]$到$LCA$的链上查一次$r$的前驱和后继更新答案即可。
注意:参数不要传反、别一个特判把自己判掉、pre和nxt的代码不要粘贴,粘贴了不要忘记改掉内部递归函数……
(昨天下午大概帮3、4个人调这题代码???RP++)
#include<bits/stdc++.h> #define rint register int using namespace std; const int N=100005,M=1000000000; inline void read(int &A) { A=0;int B=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')B=-1;ch=getchar();} while(ch>='0'&&ch<='9'){A=(A<<3)+(A<<1)+ch-'0';ch=getchar();} A=A*B; } int n,q,tp,ans,a[N],p[N]; int v[N<<1],nxt[N<<1],first[N<<1],tot; int root[N],ls[N<<6],rs[N<<6],val[N<<6],cnt; int dep[N],f[N][23]; inline void build_line(int uu,int vv) { v[++tot]=vv,nxt[tot]=first[uu]; first[uu]=tot;return ; } inline void insert(int &k,int l,int r,int his,int dat) { k=++cnt;val[k]=val[his]+1; if(l==r)return ; ls[k]=ls[his],rs[k]=rs[his]; int mid=(l+r)>>1; if(dat<=mid)insert(ls[k],l,mid,ls[his],dat); else insert(rs[k],mid+1,r,rs[his],dat); } inline int get_pre(int k1,int k2,int l,int r,int dat) { if(!(val[k2]-val[k1]))return 0; if(l==r)return l;int mid=(l+r)>>1; if(dat<=mid)return get_pre(ls[k1],ls[k2],l,mid,dat); int lin=get_pre(rs[k1],rs[k2],mid+1,r,dat); if(!lin)return get_pre(ls[k1],ls[k2],l,mid,dat); return lin; } inline int get_nxt(int k1,int k2,int l,int r,int dat) { if(!(val[k2]-val[k1]))return 0; if(l==r)return l;int mid=(l+r)>>1; if(dat>mid)return get_nxt(rs[k1],rs[k2],mid+1,r,dat); int lin=get_nxt(ls[k1],ls[k2],l,mid,dat); if(!lin)return get_nxt(rs[k1],rs[k2],mid+1,r,dat); return lin; } inline void bfs() { queue <int> q; q.push(1);dep[1]=1; while(!q.empty()) { int x=q.front();q.pop(); for(rint i=first[x];i;i=nxt[i]) { int y=v[i];if(dep[y])continue; dep[y]=dep[x]+1;f[y][0]=x; for(rint i=1;i<=20;++i) f[y][i]=f[f[y][i-1]][i-1]; q.push(y); } } return ; } inline int get_lca(int x,int y) { if(dep[x]<dep[y])swap(x,y); for(rint i=20;i>=0;--i) if(dep[f[x][i]]>=dep[y])x=f[x][i]; if(x==y)return x; for(rint i=20;i>=0;--i) if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; return f[x][0]; } inline void dfs_build(int x,int fa) { insert(root[x],1,M,root[fa],a[x]); for(rint i=first[x];i;i=nxt[i]) if(v[i]!=fa)dfs_build(v[i],x); return ; } int main() { read(n),read(q),read(tp); for(rint i=1;i<=n;++i)read(a[i]); for(rint i=1,ST,EN;i<n;++i) read(ST),read(EN),build_line(ST,EN),build_line(EN,ST); dfs_build(1,0);bfs(); for(rint i=1,r,k;i<=q;++i) { read(r),read(k); for(rint j=1,x;j<=k;++j) read(x),p[j]=(x-1+ans*tp)%n+1; int lca=p[1]; for(rint j=2;j<=k;++j) lca=get_lca(lca,p[j]); ans=0x7fffffff; for(rint j=1;j<=k;++j) { int pre=get_pre(root[f[lca][0]],root[p[j]],1,M,r); int nxt=get_nxt(root[f[lca][0]],root[p[j]],1,M,r); if(pre)ans=min(r-pre,ans); if(nxt)ans=min(nxt-r,ans); } printf("%d\n",ans); } }