博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

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();
}
View Code

 

posted @ 2017-04-26 07:25  swm_sxt  阅读(202)  评论(0编辑  收藏  举报