#include<cstdio>#include<cctype>
namespace fast_IO
{constint IN_LEN=10000000,OUT_LEN=10000000;char ibuf[IN_LEN],obuf[OUT_LEN],*ih=ibuf+IN_LEN,*oh=obuf,*lastin=ibuf+IN_LEN,*lastout=obuf+OUT_LEN-1;inlinechargetchar_(){return(ih==lastin)&&(lastin=(ih=ibuf)+fread(ibuf,1,IN_LEN,stdin),ih==lastin)?EOF:*ih++;}inlinevoidputchar_(constchar x){if(oh==lastout)fwrite(obuf,1,oh-obuf,stdout),oh=obuf;*oh++=x;}inlinevoidflush(){fwrite(obuf,1,oh-obuf,stdout);}}
using namespace fast_IO;#define getchar() getchar_()#define putchar(x) putchar_((x))typedeflonglong LL;#define rg register
template <typename T>inline T max(const T a,const T b){return a>b?a:b;}
template <typename T>inline T min(const T a,const T b){return a<b?a:b;}
template <typename T>inline T abs(const T a){return a>0?a:-a;}
template <typename T>inlinevoidswap(T&a,T&b){T c=a;a=b;b=c;}
template <typename T>inline T gcd(const T a,const T b){if(a%b==0)return b;returngcd(b,a%b);}
template <typename T>inline T square(const T x){return x*x;};
template <typename T>inlinevoidread(T&x){char cu=getchar();x=0;bool fla=0;while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}while(isdigit(cu))x=x*10+cu-'0',cu=getchar();if(fla)x=-x;}
template <typename T>voidprinte(const T x){if(x>=10)printe(x/10);putchar(x%10+'0');}
template <typename T>inlinevoidprint(const T x){if(x<0)putchar('-'),printe(-x);elseprinte(x);}inlinevoidjudge(){freopen("1.in","r",stdin);freopen("1.out","w",stdout);}#include<cstring>#include<algorithm>constint maxn=250001,maxm=500001;int bit[19];int n,m,s;int head[maxn],nxt[maxm],tow[maxm],vau[maxm],tmp=1;int who[maxn][19],dis[maxn][19];int dep[maxn];inlinevoidaddb(constint u,constint v,constint w){tmp++;nxt[tmp]=head[u];head[u]=tmp;tow[tmp]=v;vau[tmp]=w;}int tid[maxn],tim;inlinevoiddfs(constint u){tid[u]=++tim;for(rg int i=head[u];i;i=nxt[i]){constint v=tow[i];if(who[u][0]!=v){who[v][0]=u;dis[v][0]=vau[i];dep[v]=dep[u]+1;dfs(v);}}}inlineintlca(int a,int b){if(dep[a]<dep[b])swap(a,b);constint lenth=dep[a]-dep[b];for(rg int i=0;bit[i]<=lenth;i++)if(lenth&bit[i])a=who[a][i];if(a==b)return a;for(rg int i=18;i>=0;i--)if(who[a][i]!=who[b][i])a=who[a][i],b=who[b][i];return who[a][0];}inlineintdist(int a,int b){rg int ans=0x7fffffff;if(dep[a]<dep[b])swap(a,b);constint lenth=dep[a]-dep[b];for(rg int i=0;bit[i]<=lenth;i++)if(lenth&bit[i])ans=min(ans,dis[a][i]),a=who[a][i];if(a==b)return ans;for(rg int i=18;i>=0;i--)if(who[a][i]!=who[b][i])ans=min(ans,min(dis[a][i],dis[b][i])),a=who[a][i],b=who[b][i];returnmin(ans,min(dis[a][0],dis[b][0]));}int head_[maxn],nxt_[maxm],tow_[maxm],vau_[maxm],tmp_;inlinevoidaddb_(constint u,constint v,constint w){tmp_++;nxt_[tmp_]=head_[u];head_[u]=tmp_;tow_[tmp_]=v;vau_[tmp_]=w;}int k,h[maxn];
bool cmp(constint x,constint y){return tid[x]<tid[y];}int stack[maxn],top;
LL dp[maxn][2];voiddfs(constint u,constint fa){rg bool sign=1;dp[u][0]=dp[u][1]=0;for(rg int i=head_[u];i;i=nxt_[i]){constint v=tow_[i];if(v!=fa){dfs(v,u);dp[u][0]+=min(dp[v][0],dp[v][1]+vau_[i]);dp[u][1]+=dp[v][1];sign=0;}}head_[u]=0;if(sign)dp[u][0]=0x7fffffffffffffff;dp[u][1]=min(dp[u][1],dp[u][0]);}intmain(){// judge();memset(dis,0x7f,sizeof(dis));bit[0]=1;for(rg int i=1;i<=18;i++)bit[i]=bit[i-1]<<1;read(n),s=1;for(rg int i=1;i<n;i++){int u,v,w;read(u),read(v),read(w);addb(u,v,w),addb(v,u,w);}who[s][0]=s,dep[s]=1;dfs(s);for(rg int j=1;j<=18;j++)for(rg int i=1;i<=n;i++)who[i][j]=who[who[i][j-1]][j-1],dis[i][j]=min(dis[i][j-1],dis[who[i][j-1]][j-1]);read(m);for(rg int i=1;i<=m;i++){read(k);for(rg int j=1;j<=k;j++)read(h[j]);std::sort(h+1,h+k+1,cmp);tmp_=0;rg int sum=0;h[++sum]=h[1];for(rg int j=2;j<=k;j++)if(lca(h[sum],h[j])!=h[sum])h[++sum]=h[j];k=sum;top=0,stack[++top]=1;for(rg int j=1;j<=k;j++){constint LCA=lca(stack[top],h[j]);while(top>1&&dep[stack[top-1]]>dep[LCA]){constint DIS=dist(stack[top-1],stack[top]);addb_(stack[top-1],stack[top],DIS),addb_(stack[top],stack[top-1],DIS);top--;}if(dep[stack[top]]>dep[LCA]){constint DIS=dist(LCA,stack[top]);addb_(LCA,stack[top],DIS),addb_(stack[top],LCA,DIS);top--;}if(!top||dep[stack[top]]<dep[LCA])stack[++top]=LCA;stack[++top]=h[j];}while(top>1){constint DIS=dist(stack[top-1],stack[top]);addb_(stack[top-1],stack[top],DIS),addb_(stack[top],stack[top-1],DIS);top--;}dfs(1,0);print(dp[1][0]);putchar('\n');}return0;}
#include<cstdio>#include<cctype>#include<algorithm>#include<cstring>
namespace fast_IO
{constint IN_LEN=10000000,OUT_LEN=10000000;char ibuf[IN_LEN],obuf[OUT_LEN],*ih=ibuf+IN_LEN,*oh=obuf,*lastin=ibuf+IN_LEN,*lastout=obuf+OUT_LEN-1;inlinechargetchar_(){return(ih==lastin)&&(lastin=(ih=ibuf)+fread(ibuf,1,IN_LEN,stdin),ih==lastin)?EOF:*ih++;}inlinevoidputchar_(constchar x){if(oh==lastout)fwrite(obuf,1,oh-obuf,stdout),oh=obuf;*oh++=x;}inlinevoidflush(){fwrite(obuf,1,oh-obuf,stdout);}}
using namespace fast_IO;#define getchar() getchar_()#define putchar(x) putchar_((x))#define rg registertypedeflonglong LL;
template <typename T>inline T max(const T a,const T b){return a>b?a:b;}
template <typename T>inline T min(const T a,const T b){return a<b?a:b;}
template <typename T>inlinevoidmind(T&a,const T b){a=a<b?a:b;}
template <typename T>inlinevoidmaxd(T&a,const T b){a=a>b?a:b;}
template <typename T>inline T abs(const T a){return a>0?a:-a;}
template <typename T>inlinevoidswap(T&a,T&b){T c=a;a=b;b=c;}
template <typename T>inline T gcd(const T a,const T b){if(!b)return a;returngcd(b,a%b);}
template <typename T>inline T lcm(const T a,const T b){return a/gcd(a,b)*b;}
template <typename T>inline T square(const T x){return x*x;};
template <typename T>inlinevoidread(T&x){char cu=getchar();x=0;bool fla=0;while(!isdigit(cu)){if(cu=='-')fla=1;cu=getchar();}while(isdigit(cu))x=x*10+cu-'0',cu=getchar();if(fla)x=-x;}
template <typename T>inlinevoidprinte(const T x){if(x>=10)printe(x/10);putchar(x%10+'0');}
template <typename T>inlinevoidprint(const T x){if(x<0)putchar('-'),printe(-x);elseprinte(x);}constint maxn=300001,maxm=600001;int bit[19];int n,m,s;int head[maxn],nxt[maxm],tow[maxm],tmp=1;int who[maxn][19],dis[maxn][19];int dep[maxn];inlinevoidaddb(constint u,constint v){tmp++;nxt[tmp]=head[u];head[u]=tmp;tow[tmp]=v;}int tid[maxn],tim,size[maxn];inlinevoiddfs(constint u){tid[u]=++tim,size[u]=1;for(rg int i=head[u];i;i=nxt[i]){constint v=tow[i];if(who[u][0]!=v){who[v][0]=u;dis[v][0]=1;dep[v]=dep[u]+1;dfs(v);size[u]+=size[v];}}}inlineintlca(int a,int b){if(dep[a]<dep[b])swap(a,b);constint lenth=dep[a]-dep[b];for(rg int i=0;bit[i]<=lenth;i++)if(lenth&bit[i])a=who[a][i];if(a==b)return a;for(rg int i=18;i>=0;i--)if(who[a][i]!=who[b][i])a=who[a][i],b=who[b][i];return who[a][0];}inlineintdist(int a,int b){rg int ans=0;if(dep[a]<dep[b])swap(a,b);constint lenth=dep[a]-dep[b];for(rg int i=0;bit[i]<=lenth;i++)if(lenth&bit[i])ans+=dis[a][i],a=who[a][i];if(a==b)return ans;for(rg int i=18;i>=0;i--)if(who[a][i]!=who[b][i])ans+=dis[a][i]+dis[b][i],a=who[a][i],b=who[b][i];return ans+dis[a][0]+dis[b][0];}int head_[maxn],nxt_[maxm],tow_[maxm],vau_[maxm],tmp_;inlinevoidaddb_(constint u,constint v,constint w){tmp_++;nxt_[tmp_]=head_[u];head_[u]=tmp_;tow_[tmp_]=v;vau_[tmp_]=w;}int k,h[maxn],ans[maxn],belo[maxn],Dis[maxn];int qu[maxn];
bool sign[maxn];
bool cmp(constint x,constint y){return tid[x]<tid[y];}int stack[maxn],top;inlineintcheck(int u,constint lenth){for(rg int i=0;bit[i]<=lenth;i++)if(lenth&bit[i])u=who[u][i];return u;}voiddfs1_0(constint u,constint fa){if(sign[u]){for(rg int i=head_[u];i;i=nxt_[i]){constint v=tow_[i];if(v!=fa)dfs1_0(v,u);}}else{for(rg int i=head_[u];i;i=nxt_[i]){constint v=tow_[i];if(v!=fa){dfs1_0(v,u);if(sign[v]){if(vau_[i]<Dis[u]||vau_[i]==Dis[u]&&v<belo[u])belo[u]=v,Dis[u]=vau_[i];}else{if(vau_[i]+Dis[v]<Dis[u]||vau_[i]+Dis[v]==Dis[u]&&belo[v]<belo[u])belo[u]=belo[v],Dis[u]=vau_[i]+Dis[v];}}}}}voiddfs1_1(constint u,constint fa){if(sign[u]){for(rg int i=head_[u];i;i=nxt_[i]){constint v=tow_[i];if(v!=fa)dfs1_1(v,u);}}else{for(rg int i=head_[u];i;i=nxt_[i]){constint v=tow_[i];if(v==fa){if(sign[v]){if(vau_[i]<Dis[u]||vau_[i]==Dis[u]&&v<belo[u])belo[u]=v,Dis[u]=vau_[i];}else{if(vau_[i]+Dis[v]<Dis[u]||vau_[i]+Dis[v]==Dis[u]&&belo[v]<belo[u])belo[u]=belo[v],Dis[u]=vau_[i]+Dis[v];}}}for(rg int i=head_[u];i;i=nxt_[i]){constint v=tow_[i];if(v!=fa)dfs1_1(v,u);}}}voiddfs2(constint u,constint fa){if(sign[u]){for(rg int i=head_[u];i;i=nxt_[i]){constint v=tow_[i];if(v!=fa)dfs2(v,u);}}else{ans[u]=0;for(rg int i=head_[u];i;i=nxt_[i]){constint v=tow_[i];if(belo[v]==belo[u]&&Dis[u]>Dis[v]||v==belo[u])continue;rg int p;if(v!=fa)dfs2(v,u);if(belo[v]==belo[u])ans[u]+=ans[v];elseif(sign[v]){if(v!=fa){if((Dis[u]+vau_[i])&1)p=check(v,(Dis[u]+vau_[i])/2);elseif(v<belo[u])p=check(v,(Dis[u]+vau_[i])/2);else p=check(v,(Dis[u]+vau_[i])/2-1);ans[u]+=size[p];}else{if((Dis[u]+vau_[i])&1)p=check(u,(Dis[u]+vau_[i])/2-Dis[u]);elseif(v>belo[u])p=check(u,(Dis[u]+vau_[i])/2-Dis[u]);else p=check(u,(Dis[u]+vau_[i])/2-Dis[u]-1);ans[u]+=n-size[p];}}else{if(v!=fa){if((Dis[u]+Dis[v]+vau_[i])&1)p=check(v,(Dis[u]+Dis[v]+vau_[i])/2-Dis[v]);elseif(belo[v]<belo[u])p=check(v,(Dis[u]+Dis[v]+vau_[i])/2-Dis[v]);else p=check(v,(Dis[u]+Dis[v]+vau_[i])/2-Dis[v]-1);ans[u]+=size[p];}else{if((Dis[u]+Dis[v]+vau_[i])&1)p=check(u,(Dis[u]+Dis[v]+vau_[i])/2-Dis[u]);elseif(belo[v]>belo[u])p=check(u,(Dis[u]+Dis[v]+vau_[i])/2-Dis[u]);else p=check(u,(Dis[u]+Dis[v]+vau_[i])/2-Dis[u]-1);ans[u]+=n-size[p];}}}for(rg int i=head_[u];i;i=nxt_[i]){constint v=tow_[i];if(belo[v]==belo[u]&&Dis[u]>Dis[v]||v==belo[u])if(v!=fa)dfs2(v,u);}}}voiddfs3(constint u,constint fa){if(sign[u]){ans[u]=n;for(rg int i=head_[u];i;i=nxt_[i]){constint v=tow_[i];rg int p;if(v!=fa)dfs3(v,u);if(belo[v]==u)ans[u]-=ans[v];elseif(sign[v]){if(v!=fa){if(vau_[i]&1)p=check(v,vau_[i]/2);elseif(v<u)p=check(v,vau_[i]/2);else p=check(v,vau_[i]/2-1);ans[u]-=size[p];}else{if(vau_[i]&1)p=check(u,vau_[i]/2);elseif(v>u)p=check(u,vau_[i]/2);else p=check(u,vau_[i]/2-1);ans[u]-=n-size[p];}}else{if(v!=fa){if((Dis[v]+vau_[i])&1)p=check(v,(Dis[v]+vau_[i])/2-Dis[v]);elseif(u<belo[v])p=check(v,(Dis[v]+vau_[i])/2-Dis[v]-1);else p=check(v,(Dis[v]+vau_[i])/2-Dis[v]);ans[u]-=size[p];}else{if((Dis[v]+vau_[i])&1)p=check(u,(Dis[v]+vau_[i])/2);elseif(u>belo[v])p=check(u,(Dis[v]+vau_[i])/2-1);else p=check(u,(Dis[v]+vau_[i])/2);ans[u]-=n-size[p];}}}}else{for(rg int i=head_[u];i;i=nxt_[i]){constint v=tow_[i];if(v!=fa)dfs3(v,u);}}}voiddfs4(constint u,constint fa){if(sign[u]){for(rg int i=head_[u];i;i=nxt_[i]){constint v=tow_[i];if(v!=fa)dfs4(v,u);}sign[u]=0;}else{for(rg int i=head_[u];i;i=nxt_[i]){constint v=tow_[i];if(v!=fa)dfs4(v,u);}belo[u]=0;}head_[u]=0,Dis[u]=0x7f7f7f7f;}intmain(){memset(Dis,0x7f,sizeof(Dis));bit[0]=1;for(rg int i=1;i<=18;i++)bit[i]=bit[i-1]<<1;read(n),s=1;for(rg int i=1;i<n;i++){int u,v;read(u),read(v);addb(u,v),addb(v,u);}who[s][0]=s,dep[s]=1;dfs(s);for(rg int j=1;j<=18;j++)for(rg int i=1;i<=n;i++)who[i][j]=who[who[i][j-1]][j-1],dis[i][j]=dis[i][j-1]+dis[who[i][j-1]][j-1];read(m);for(rg int i=1;i<=m;i++){read(k);for(rg int j=1;j<=k;j++)read(h[j]),qu[j]=h[j],sign[h[j]]=1,Dis[h[j]]=0;std::sort(h+1,h+k+1,cmp);tmp_=0;top=0,stack[++top]=h[1];for(rg int j=2;j<=k;j++){constint LCA=lca(stack[top],h[j]);while(top>1&&dep[stack[top-1]]>dep[LCA]){constint DIS=dist(stack[top-1],stack[top]);addb_(stack[top-1],stack[top],DIS),addb_(stack[top],stack[top-1],DIS);top--;}if(dep[stack[top]]>dep[LCA]){constint DIS=dist(LCA,stack[top]);addb_(LCA,stack[top],DIS),addb_(stack[top],LCA,DIS);top--;}if(!top||dep[stack[top]]<dep[LCA])stack[++top]=LCA;stack[++top]=h[j];}while(top>1){constint DIS=dist(stack[top-1],stack[top]);addb_(stack[top-1],stack[top],DIS),addb_(stack[top],stack[top-1],DIS);top--;}dfs1_0(stack[1],0);dfs1_1(stack[1],0);dfs2(stack[1],0);dfs3(stack[1],0);dfs4(stack[1],0);for(rg int i=1;i<=k;i++)print(ans[qu[i]]),putchar(' ');putchar('\n');}returnflush(),0;}
總結
上面兩道例題差不多覆蓋了差不多虛樹要用到的所以基礎操作了,總結一個虛樹的板子還是挺好的,虛樹寫起來簡單,也挺好用的,復雜度也挺優秀,值得好好研究一番 update by 2018.3:感謝Michael_Li對本篇博客的建議與指正 update by 2019.1:對部分公式進行了美化更新