zoukankan      html  css  js  c++  java
  • 洛谷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("
    ");
    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 }
  • 相关阅读:
    个人阅读作业+个人总结
    个人作业Week3-案例分析
    个人作业Week2-代码复审
    个人作业-Week1
    个人项目-数独
    第0次个人作业
    团队项目-游戏引擎的考察
    Week3结对项目-数独游戏
    个人作业Week3-案例分析
    代码复审
  • 原文地址:https://www.cnblogs.com/w-h-h/p/8626271.html
Copyright © 2011-2022 走看看