[lca][主席树] Jzoj P5850 e

Description

 

Input

Output

 

Sample Input

见下发文件

Sample Output

见下发文件
 
 

Data Constraint

 

 

题解

  • 首先,对于一个最小联通块就是从每个点出发,到他们所有点公共的lca的所有链组成
  • 那么我们就需要查询一条到祖先的链上的权值中r的前驱后继
  • 然后就是主席树

代码

 

 1 #include <cstdio>
 2 #include <iostream>
 3 #include <algorithm> 
 4 using namespace std;
 5 const int mx=1e5+10,inf=1e9,inf1=2e9;
 6 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];
 7 struct edge{int to,from;}e[mx*2];
 8 void insert(int x,int y) { e[++cnt].to=y; e[cnt].from=head[x]; head[x]=cnt; }
 9 void add(int &d,int x,int l,int r,int y,int k)
10 {
11     if (!d) d=++cnt;
12     sum[d]=sum[x]+k;
13     if (l==r) return;
14     int mid=(l+r)>>1;
15     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);
16 }
17 void dfs(int x,int fa)
18 {
19     dep[x]=dep[fa]+1,f[x][0]=fa;
20     add(T[x],T[fa],1,inf,a[x],1);
21     for (int i=head[x];i;i=e[i].from)
22         if (e[i].to!=fa)
23             dfs(e[i].to,x);
24 }
25 int getlca(int x,int y)
26 {
27     if (dep[x]<dep[y]) swap(x,y);
28     for (int i=19;i>=0;i--)
29         if (dep[f[x][i]]>=dep[y])
30            x=f[x][i];
31     if (x==y) return x;
32     for (int i=19;i>=0;i--)
33         if (f[x][i]!=f[y][i])
34             x=f[x][i],y=f[y][i];
35     return f[x][0];
36 }
37 int getpre(int x,int y,int l,int r,int d)
38 {
39     if (!(sum[x]-sum[y])) return 0;
40     if (l==r) return l;
41     int mid=(l+r)>>1,w;
42     if (d<=mid) return getpre(L[x],L[y],l,mid,d);
43     else 
44     {
45         if ((w=getpre(R[x],R[y],mid+1,r,d))) return w;
46         return getpre(L[x],L[y],l,mid,d);
47     }
48 }
49 int getnxt(int x,int y,int l,int r,int d)
50 {
51     if (!(sum[x]-sum[y])) return 0;
52     if (l==r) return l;
53     int mid=(l+r)>>1,w;
54     if (d>mid) return getnxt(R[x],R[y],mid+1,r,d);
55     else 
56     {
57         if ((w=getnxt(L[x],L[y],l,mid,d))) return w;
58         return getnxt(R[x],R[y],mid+1,r,d);
59     }
60 }
61 int main()
62 {
63     freopen("e.in","r",stdin);
64     freopen("e.out","w",stdout);
65     scanf("%d%d%d",&n,&q,&type);
66     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
67     for (int i=1;i<=n-1;i++)
68     {
69         int u,v;
70         scanf("%d%d",&u,&v);
71         insert(u,v),insert(v,u);
72     }
73     cnt=0,dfs(1,0);
74     for (int j=1;j<20;j++)
75         for (int i=1;i<=n;i++)
76             f[i][j]=f[f[i][j-1]][j-1];
77     for (int i=1;i<=q;i++)
78     {
79         int r,k; 
80         scanf("%d%d",&r,&k);
81         for (int j=1;j<=k;j++)
82         {
83             scanf("%d",&x[j]);
84             x[j]=(x[j]-1+ans*type)%n+1;
85         }
86         int lca=x[1];
87         for (int j=2;j<=k;j++) lca=getlca(lca,x[j]);
88         lca=f[lca][0],ans=inf1;
89         for (int j=1;j<=k;j++)
90         {
91             int ans1=getpre(T[x[j]],T[lca],1,inf,r),
92                 ans2=getnxt(T[x[j]],T[lca],1,inf,r);
93             if (ans1) ans=min(ans,r-ans1);
94             if (ans2) ans=min(ans,ans2-r);
95         }
96         printf("%d\n",ans);
97     }
98 }

 

posted @ 2018-09-14 20:45  BEYang_Z  阅读(119)  评论(0编辑  收藏  举报