洛谷P3233 [HNOI2014]世界树

Posted white_hat_hacker

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷P3233 [HNOI2014]世界树相关的知识,希望对你有一定的参考价值。

虚树= =

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<vector>
  6 #define INF 0x7f7f7f7f
  7 #define MAXN 300005
  8 #define LOG 20
  9 #define rint register int
 10 #define pb push_back
 11 #define pii pair<int,int>
 12 #define mp make_pair
 13 #define ft first
 14 #define sc second
 15 using namespace std;
 16 int read(){
 17     int x=0,f=1;char ch=getchar();
 18     while(ch<0||ch>9){if(-==ch)f=-1;ch=getchar();}
 19     while(ch>=0&&ch<=9){x=x*10+ch-0;ch=getchar();}
 20     return x*f;
 21 }
 22 int fst1[MAXN],nxt1[MAXN<<1],from1[MAXN<<1],to1[MAXN<<1],cnte;
 23 int fst[MAXN],nxt[MAXN<<1],from[MAXN<<1],to[MAXN<<1],cnt;
 24 void add(int x,int y){
 25     nxt[++cnt]=fst[x],fst[x]=cnt,from[cnt]=x,to[cnt]=y;
 26     nxt[++cnt]=fst[y],fst[y]=cnt,from[cnt]=y,to[cnt]=x;
 27 }
 28 void add1(int x,int y){
 29     nxt1[++cnte]=fst1[x],fst1[x]=cnte,from1[cnte]=x,to1[cnte]=y;
 30     nxt1[++cnte]=fst1[y],fst1[y]=cnte,from1[cnte]=y,to1[cnte]=x;
 31 }
 32 int n,m;
 33 int h[MAXN];
 34 int dep[MAXN],fa[MAXN][LOG],sz[MAXN];
 35 int dfn[MAXN],idx;
 36 int b[MAXN],pa[MAXN];
 37 int lca(int x,int y){
 38     if(dep[x]<dep[y])swap(x,y);
 39     for(rint d=dep[x]-dep[y],k=0;d;d>>=1,k++){
 40         if(d&1)x=fa[x][k];
 41     }
 42     if(x==y)return x;
 43     for(rint k=LOG-1;k>=0;k--){
 44         if(fa[x][k]!=fa[y][k]){
 45             x=fa[x][k],y=fa[y][k];
 46         }
 47     }
 48     return fa[x][0];
 49 }
 50 void dfs1(int x){
 51     sz[x]=1;
 52     dfn[x]=(++idx);
 53     for(rint e=fst1[x];e;e=nxt1[e]){
 54         int y=to1[e];
 55         if(y!=fa[x][0]){
 56             fa[y][0]=x;
 57             dep[y]=dep[x]+1;
 58             dfs1(y);
 59             sz[x]+=sz[y];
 60         }
 61     }
 62 }
 63 bool comp(const int &A,const int &B){
 64     return (dfn[A]<dfn[B]);
 65 }
 66 bool comp1(const int A,const int &B){
 67     return (dep[A]>dep[B]);
 68 }
 69 int sta[MAXN],top,rt,t[MAXN],tot;
 70 pii d[MAXN];
 71 void dfs(int x){
 72     for(rint e=fst[x];e;e=nxt[e]){
 73         int y=to[e];
 74         if(y!=pa[x]){
 75             d[y]=min(d[y],mp(d[x].ft+dep[y]-dep[x],d[x].sc));
 76             dfs(y);
 77         }
 78     }
 79 }
 80 void pop(int p){
 81     pa[sta[top]]=p;
 82     add(sta[top],p);
 83     b[sta[top]]=1;
 84     t[++tot]=sta[top];
 85     top--;    
 86 }
 87 int h1[MAXN];
 88 void init(){
 89     cnt=0;
 90     memset(fst,0,sizeof(fst));
 91     memset(nxt,0,sizeof(nxt));
 92     memset(from,0,sizeof(from));
 93     memset(to,0,sizeof(to));
 94     memset(b,0,sizeof(b));
 95     memset(pa,0,sizeof(pa));
 96     memcpy(h1,h,sizeof(h1));
 97     sort(h+1,h+m+1,comp);
 98     top=tot=0;
 99     sta[++top]=h[1];
100     int x,y;
101     for(rint i=2;i<=m;i++){
102         x=h[i],y=lca(x,sta[top]);
103         while(dep[sta[top-1]]>=dep[y]){
104             pop(sta[top-1]);
105         }
106         if(dep[sta[top]]==dep[y]){
107             sta[++top]=x;
108         }
109         else{
110             pop(y);
111             sta[++top]=y;
112             sta[++top]=x;
113         }
114     }
115     while(top){
116         pop(sta[top-1]);
117     }
118     rt=sta[1];
119     for(rint i=1;i<=tot;i++)d[t[i]]=mp(INF,0);
120     for(rint i=1;i<=m;i++)d[h[i]]=mp(0,h[i]);
121     sort(t+1,t+tot+1,comp1);
122     for(rint i=1;i<=tot;i++){
123         x=t[i];
124         d[pa[x]]=min(d[pa[x]],mp(d[x].ft-dep[pa[x]]+dep[x],d[x].sc));
125     }
126     dfs(rt);
127 }
128 int ans[MAXN];
129 int LA(int x,int L){
130     for(rint k=L,p=0;k;k>>=1,p++){
131         if(k&1){
132             x=fa[x][p];
133         }
134     }
135     return x;
136 }
137 int workup(int x,int f,int L){
138     if(L<=0)return 0;
139     int y=LA(x,min(L,dep[x]-dep[f]-1));
140     return sz[y]-sz[x];
141 }
142 int workdown(int x,int f,int L){
143     if(L<=0)return 0;
144     int y=LA(x,dep[x]-dep[f]-1);
145     int z=LA(x,max(dep[x]-dep[f]-1-L,0));
146     return sz[y]-sz[z];
147 }
148 void work(int x,int f){
149     int t=d[f].ft+d[x].ft+dep[x]-dep[f]-1;
150     int L=t>>1;
151     if(t&1){
152         ans[d[x].sc]+=workup(x,f,L-d[x].ft);
153         ans[d[f].sc]+=workdown(x,f,L-d[f].ft);
154         ans[min(d[x].sc,d[f].sc)]+=workup(x,f,L+1-d[x].ft)-workup(x,f,L-d[x].ft);
155     }
156     else{
157         ans[d[x].sc]+=workup(x,f,L-d[x].ft);
158         ans[d[f].sc]+=workdown(x,f,L-d[f].ft);
159     }
160 }
161 void solve(){
162     memset(ans,0,sizeof(ans));
163     int x;
164     for(rint i=1;i<=tot;i++){
165         x=t[i];
166         ans[d[x].sc]+=sz[x];
167         int y=LA(x,dep[x]-dep[pa[x]]-1);
168         ans[d[pa[x]].sc]-=sz[y];
169     }
170     ans[d[rt].sc]+=sz[1]-sz[rt];
171     for(rint i=1;i<=tot;i++){
172         x=t[i];if(x==rt)continue;
173         work(x,pa[x]);    
174     }
175     for(rint i=1;i<=m;i++){
176         printf("%d ",ans[h1[i]]);
177     }printf("\n");
178 }
179 int main()
180 {
181 //    freopen("data.in","r",stdin);
182     n=read();
183     int x,y;
184     for(rint i=1;i<n;i++){
185         x=read(),y=read();
186         add1(x,y);
187     }
188     dep[1]=1; 
189     dfs1(1);
190     for(rint k=1;k<LOG;k++){
191         for(rint i=1;i<=n;i++){
192             fa[i][k]=fa[fa[i][k-1]][k-1];
193         }
194     }
195     int q=read();
196     while(q--){
197         m=read();
198         for(rint i=1;i<=m;i++)h[i]=read();
199         init();
200         solve();
201     }
202     return 0;
203 }

 

以上是关于洛谷P3233 [HNOI2014]世界树的主要内容,如果未能解决你的问题,请参考以下文章

题解 P3233 [HNOI2014]世界树

[BZOJ3572][HNOI2014]世界树(虚树DP)

HNOI2014世界树

[BZOJ3572][Hnoi2014]世界树

BZOJ:3572: [Hnoi2014]世界树

[HNOI2014]世界树