BZOJ:3572: [Hnoi2014]世界树
Posted Swm_sxt
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ:3572: [Hnoi2014]世界树相关的知识,希望对你有一定的参考价值。
3572: [Hnoi2014]世界树
虚树模版
#include<cstdio> #include<algorithm> #define MN 300001 using namespace std; int read_p,read_ca; inline int read(){ read_p=0;read_ca=getchar(); while(read_ca<‘0‘||read_ca>‘9‘) read_ca=getchar(); while(read_ca>=‘0‘&&read_ca<=‘9‘) read_p=read_p*10+read_ca-48,read_ca=getchar(); return read_p; } struct na{int y,ne;}b[MN<<1],_b[MN<<1]; int n,m,q,x,y,df[MN],num=0,l[MN],lo[MN],f[MN][20],st[MN*3],de[MN],ST[MN*3],top,_l[MN],_num,u[MN],D[MN],s[MN],dis[MN],nm,p[MN]; bool bo[MN]; inline void in(int x,int y){b[++num].y=y;b[num].ne=l[x];l[x]=num;} inline void _in(int x,int y){_b[++_num].y=y;_b[_num].ne=_l[x];_l[x]=_num;} void dfs(int x,int F){ df[x]=++nm;s[x]=1; for (int i=1;i<20;i++) if (f[f[x][i-1]][i-1]) f[x][i]=f[f[x][i-1]][i-1]; for (register int i=l[x];i;i=b[i].ne) if (b[i].y!=F) f[b[i].y][0]=x,de[b[i].y]=de[x]+1,dfs(b[i].y,x),s[x]+=s[b[i].y]; lo[x]=nm; } inline int abs(int x){return x<0?-x:x;} bool cmp(int a,int b){return df[a]<df[b];} inline int lca(int x,int y){ if (de[x]<de[y]) swap(x,y); for (int i=19;i>=0;i--) if (f[x][i]&&de[f[x][i]]>=de[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]; } inline bool _cmp(int x,int z,int y){ if (de[z]-de[x]==de[y]-de[z]) return y<z;else return de[y]-de[z]<de[z]-de[x]; } inline int work(int x,int y,int a,int b,int A,int B){ int u=y; for (int i=19;i>=0;i--) if (f[u][i]&&de[f[u][i]]>=de[x]&&(de[f[u][i]]-de[x]+a>de[y]-de[f[u][i]]+b||(de[f[u][i]]-de[x]+a==de[y]-de[f[u][i]]+b&&B<A))) u=f[u][i]; return u; } inline int maxup(int x,int y){ for (int i=19;i>=0;i--) if (de[f[y][i]]>de[x]) y=f[y][i]; return y; } void DFS(int x){ D[x]=dis[x]=0; if (bo[x]) dis[x]=x; for (int i=_l[x];i;i=_b[i].ne) if (bo[x]) DFS(_b[i].y);else if (DFS(_b[i].y),de[dis[_b[i].y]]-de[x]<abs(de[x]-de[dis[x]])||(de[dis[_b[i].y]]-de[x]==abs(de[x]-de[dis[x]])&&dis[_b[i].y]<dis[x])) dis[x]=dis[_b[i].y]; p[x]=abs(de[dis[x]]-de[x]); } void DDFS(int x,int d,int di){ if (p[x]>di||(p[x]==di&&d<dis[x])) p[x]=di,dis[x]=d; for (int i=_l[x];i;i=_b[i].ne) if (dis[x]!=dis[_b[i].y]) DDFS(_b[i].y,dis[x],p[x]+de[_b[i].y]-de[x]);else DDFS(_b[i].y,d,di+de[_b[i].y]-de[x]); } void _DFS(int x){ D[dis[x]]+=s[x]; int lo=0; for (int i=_l[x];i;i=_b[i].ne){ int o=maxup(x,_b[i].y),u=work(x,_b[i].y,p[x],p[_b[i].y],dis[x],dis[_b[i].y]); if (u==x) u=o; D[dis[x]]+=s[o]-s[u];D[dis[_b[i].y]]+=s[u]-s[_b[i].y]; if (o!=lo) D[dis[x]]-=s[o]; _DFS(_b[i].y); lo=o; } } void Mavis(){ int NUM=m=read(); for (int i=1;i<=m;i++) u[i]=st[i]=read(),bo[u[i]]=1; sort(st+1,st+1+m,cmp); for (int i=1;i<m;i++) st[++NUM]=lca(st[i+1],st[i]);st[++NUM]=1; sort(st+1,st+1+NUM,cmp);top=0; for (int i=1;i<=NUM;i++) if (st[i]!=st[i-1]){ _l[st[i]]=0; while (top&&(df[ST[top]]>df[st[i]]||lo[ST[top]]<df[st[i]])) top--; _in(ST[top],st[i]);ST[++top]=st[i]; } DFS(1);DDFS(1,0,1e9);_DFS(1); for (int i=1;i<=m;i++) printf("%d ",D[u[i]]);puts(""); for (int i=1;i<=m;i++) bo[u[i]]=0; } int main(){ register int i; n=read(); for (i=1;i<n;i++) x=read(),y=read(),in(x,y),in(y,x); dfs(1,0);de[0]=-1e9; q=read(); while (q--) Mavis(); }
以上是关于BZOJ:3572: [Hnoi2014]世界树的主要内容,如果未能解决你的问题,请参考以下文章