【JZOJ A組】e
阿新 • • 發佈:2018-12-12
Description
Input
Output
Sample Input 見下發檔案
Sample Output 見下發檔案
Data Constraint
思路
首先,對於一個最小聯通塊就是從每個點出發,到他們所有點公共的lca的所有鏈組成 那麼我們就需要查詢一條到祖先的鏈上的權值中r的前驅後繼 然後就是主席樹
程式碼
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; const int mx=1e5+10,inf=1e9,inf1=2e9; int n,q,type,cnt,ans,a[mx],T[mx],f[mx][20],dep[mx],head[mx],x[mx*3],L[mx*50],R[mx*50],sum[mx*50]; struct edge{int to,from;}e[mx*2]; void insert(int x,int y) { e[++cnt].to=y; e[cnt].from=head[x]; head[x]=cnt; } void add(int &d,int x,int l,int r,int y,int k) { if (!d) d=++cnt; sum[d]=sum[x]+k; if (l==r) return; int mid=(l+r)>>1; if (y<=mid) R[d]=R[x],add(L[d],L[x],l,mid,y,k); else L[d]=L[x],add(R[d],R[x],mid+1,r,y,k); } void dfs(int x,int fa) { dep[x]=dep[fa]+1,f[x][0]=fa; add(T[x],T[fa],1,inf,a[x],1); for (int i=head[x];i;i=e[i].from) if (e[i].to!=fa) dfs(e[i].to,x); } int getlca(int x,int y) { if (dep[x]<dep[y]) swap(x,y); for (int i=19;i>=0;i--) if (dep[f[x][i]]>=dep[y]) x=f[x][i]; if (x==y) return x; for (int i=19;i>=0;i--) if (f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i]; return f[x][0]; } int getpre(int x,int y,int l,int r,int d) { if (!(sum[x]-sum[y])) return 0; if (l==r) return l; int mid=(l+r)>>1,w; if (d<=mid) return getpre(L[x],L[y],l,mid,d); else { if ((w=getpre(R[x],R[y],mid+1,r,d))) return w; return getpre(L[x],L[y],l,mid,d); } } int getnxt(int x,int y,int l,int r,int d) { if (!(sum[x]-sum[y])) return 0; if (l==r) return l; int mid=(l+r)>>1,w; if (d>mid) return getnxt(R[x],R[y],mid+1,r,d); else { if ((w=getnxt(L[x],L[y],l,mid,d))) return w; return getnxt(R[x],R[y],mid+1,r,d); } } int main() { freopen("e.in","r",stdin); freopen("e.out","w",stdout); scanf("%d%d%d",&n,&q,&type); for (int i=1;i<=n;i++) scanf("%d",&a[i]); for (int i=1;i<=n-1;i++) { int u,v; scanf("%d%d",&u,&v); insert(u,v),insert(v,u); } cnt=0,dfs(1,0); for (int j=1;j<20;j++) for (int i=1;i<=n;i++) f[i][j]=f[f[i][j-1]][j-1]; for (int i=1;i<=q;i++) { int r,k; scanf("%d%d",&r,&k); for (int j=1;j<=k;j++) { scanf("%d",&x[j]); x[j]=(x[j]-1+ans*type)%n+1; } int lca=x[1]; for (int j=2;j<=k;j++) lca=getlca(lca,x[j]); lca=f[lca][0],ans=inf1; for (int j=1;j<=k;j++) { int ans1=getpre(T[x[j]],T[lca],1,inf,r), ans2=getnxt(T[x[j]],T[lca],1,inf,r); if (ans1) ans=min(ans,r-ans1); if (ans2) ans=min(ans,ans2-r); } printf("%d\n",ans); } }