反正肯定要建虚树,考虑建完之后怎么做
先随便dp一下算出来距离某点最近的询问点mi[x](因为有的虚树上的点它不是询问点嘛)
那我们对于某条链x到fa[x]上的非虚树上的点(包括他们的非虚树上的孩子),要么把它分给mi[x],要么分给mi[fa[x]]
我找到这个中间点以后,在原树上倍增跳过去,算他的size
这个分法是以$\frac{len[mi[x]]+len[x]+len[mi[fa[x]]]}{2}$再加加减减一些细节决定的(len[x]表示x到fa[x]的链的长度)
除此之外,每个在虚树上的点x(以及它不在虚树上的孩子),都归属于mi[x]
1 #include<bits/stdc++.h> 2 #define mp make_pair 3 #define CLR(a,x) memset(a,x,sizeof(a)) 4 using namespace std; 5 typedef long long ll; 6 typedef unsigned long long ull; 7 typedef pair<int,int> pa; 8 const int maxn=3e5+10,inf=1e9; 9 10 inline ll rd(){ 11 ll x=0;char c=getchar();int neg=1; 12 while(c<‘0‘||c>‘9‘){if(c==‘-‘) neg=-1;c=getchar();} 13 while(c>=‘0‘&&c<=‘9‘) x=x*10+c-‘0‘,c=getchar(); 14 return x*neg; 15 } 16 17 int N,Q; 18 int eg[maxn*2][2],egh[maxn],ect; 19 int fa[maxn][22],dep[maxn],dfn[maxn],tot,siz[maxn]; 20 21 inline void adeg(int a,int b){ 22 eg[++ect][0]=b,eg[ect][1]=egh[a],egh[a]=ect; 23 } 24 25 inline void dfs1(int x){ 26 dfn[x]=++tot; 27 for(int i=0;fa[x][i]&&fa[fa[x][i]][i];i++){ 28 fa[x][i+1]=fa[fa[x][i]][i]; 29 } 30 siz[x]=1; 31 for(int i=egh[x];i;i=eg[i][1]){ 32 int b=eg[i][0];if(b==fa[x][0]) continue; 33 fa[b][0]=x,dep[b]=dep[x]+1; 34 dfs1(b);siz[x]+=siz[b]; 35 } 36 } 37 38 inline int jump(int x,int d){ 39 int i=0; 40 while(d){ 41 if(d&1) x=fa[x][i]; 42 i++,d>>=1; 43 }return x; 44 } 45 46 inline int getlca(int x,int y){ 47 if(dep[x]<dep[y]) swap(x,y); 48 for(int i=log2(dep[x]-dep[y]);i>=0&&dep[x]!=dep[y];i--){ 49 if(dep[fa[x][i]]>=dep[y]) 50 x=fa[x][i]; 51 } 52 if(x==y) return x; 53 for(int i=log2(dep[x]);i>=0;i--){ 54 if(fa[x][i]!=fa[y][i]) 55 x=fa[x][i],y=fa[y][i]; 56 } 57 return fa[x][0]; 58 } 59 60 inline bool cmp(int x,int y){return dfn[x]<dfn[y];} 61 62 int xfa[maxn],xsh[maxn],xbr[maxn]; 63 64 int h[maxn],stk[maxn],hd,len[maxn]; 65 int ans[maxn],id[maxn],pct; 66 bool rea[maxn]; 67 inline void connect(int x,int y){ 68 // printf("\t\tconnect:%d %d\n",x,y); 69 xfa[x]=y,xbr[x]=xsh[y],xsh[y]=x,len[x]=dep[x]-dep[y]; 70 } 71 inline void build(int m){ 72 sort(h+1,h+m+1,cmp); 73 stk[hd=1]=1;id[++pct]=1; 74 for(int i=1;i<=m;i++){ 75 rea[h[i]]=1;id[++pct]=h[i]; 76 int lca=getlca(stk[hd],h[i]); 77 int lst=0; 78 while(dfn[stk[hd]]>dfn[lca]){ 79 if(lst) connect(lst,stk[hd]); 80 lst=stk[hd--]; 81 }if(stk[hd]!=lca) stk[++hd]=lca,id[++pct]=lca; 82 if(lst) connect(lst,stk[hd]); 83 if(h[i]!=1) stk[++hd]=h[i]; 84 } 85 while(hd>1) connect(stk[hd],stk[hd-1]),hd--; 86 } 87 pa up[maxn],dw[maxn]; 88 inline void dfs2(int x){ 89 if(rea[x]) dw[x]=mp(0,x); 90 else dw[x]=mp(inf,0); 91 for(int i=xsh[x];i;i=xbr[i]){ 92 dfs2(i); 93 dw[x]=min(dw[x],mp(dw[i].first+len[i],dw[i].second)); 94 } 95 } 96 inline void dfs3(int x){ 97 if(rea[x]) up[x]=mp(0,x); 98 else if(x==1) up[x]=mp(inf,0); 99 pa m=mp(inf,0),s=mp(inf,0); 100 for(int i=xsh[x];i;i=xbr[i]){ 101 s=min(s,mp(dw[i].first+len[i],dw[i].second)); 102 if(s<m) swap(s,m); 103 } 104 for(int i=xsh[x];i;i=xbr[i]){ 105 up[i]=mp(up[x].first+len[i],up[x].second); 106 if(dw[i].first+len[i]==m.first&&dw[i].second==m.second){ 107 up[i]=min(up[i],mp(s.first+len[i],s.second)); 108 }else up[i]=min(up[i],mp(m.first+len[i],m.second)); 109 dfs3(i); 110 } 111 if(x!=1){ 112 int n=min(dw[x],up[x]).first+len[x]+min(dw[xfa[x]],up[xfa[x]]).first,mi=min(dw[xfa[x]],up[xfa[x]]).second; 113 if(!(n&1)&&mi<min(dw[x],up[x]).second) n--; 114 n>>=1,n-=min(dw[x],up[x]).first; 115 if(n>len[x]) n--; 116 if(n>=0){ 117 int y=jump(x,n),z=jump(x,len[x]-1); 118 ans[min(dw[x],up[x]).second]+=siz[y]-siz[x],ans[mi]+=siz[z]-siz[y]; 119 } 120 121 } 122 int ss=siz[x]; 123 for(int i=xsh[x];i;i=xbr[i]) ss-=siz[jump(i,len[i]-1)]; 124 ans[min(dw[x],up[x]).second]+=ss; 125 } 126 127 128 int hh[maxn]; 129 int main(){ 130 //freopen("","r",stdin); 131 int i,j,k; 132 N=rd(); 133 for(i=1;i<N;i++){ 134 int a=rd(),b=rd(); 135 adeg(a,b);adeg(b,a); 136 }dep[1]=1;dfs1(1); 137 // for(i=1;i<=N;i++) printf("~%d %d\n",i,siz[i]); 138 Q=rd(); 139 for(i=1;i<=Q;i++){ 140 int m=rd(); 141 for(j=1;j<=m;j++) hh[j]=h[j]=rd(); 142 build(m); 143 dfs2(1),dfs3(1); 144 for(j=1;j<=m;j++) printf("%d ",ans[hh[j]]); 145 printf("\n"); 146 for(;pct;pct--) xfa[id[pct]]=xbr[id[pct]]=xsh[id[pct]]=rea[id[pct]]=ans[id[pct]]=0; 147 } 148 return 0; 149 } 150 /* 151 21 152 1 2 153 2 3 154 2 4 155 3 9 156 4 5 157 5 6 158 6 7 159 6 8 160 2 18 2 19 2 20 2 21 161 9 13 9 14 162 5 17 163 4 15 4 16 164 6 10 10 11 10 12 165 1 166 3 167 9 7 8 168 */
原文地址:https://www.cnblogs.com/Ressed/p/9997771.html
时间: 2024-10-12 19:23:55