NOIP2016D1T2......
我连D1T2都需要看题解才能做了......
AFO......
解析:
考虑有一个玩家,其起点为$u$,终点为$v$。
则其路径可以分成两部分,一部分为$u->lca(u,v)$,另一部分为$lca(u,v)->v$
对于前半部分,可以对点x(x在从下至上的路径上)产生贡献当且仅当$dis(u,x)=w_x$
由于边权均为1,因此它可以化简为$dep_u-dep_x=w_x$,然后移项得$dep_u=dep_x+w_x$
对于后半部分,当且仅当$dis(u,v)-dis(x,v)=w_x$时,可以产生贡献,化简得
$dep_u-2*dep_lca(u,v)=w_x-dep_x$.
因此可以使用树上差分维护一些桶,然后取每个点被贡献的总数,对恰好在LCA的点要-1(会被计算两次)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<vector> 5 #define N 600005 6 using namespace std; 7 int read() 8 { 9 int x=0,f=1;char ch=getchar(); 10 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 11 while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();} 12 return x*f; 13 } 14 struct tag{int v,siz;}; 15 int n,m,w[N],s[N],t[N],LCA[N],fa[N][21],T1[N+N],T2[N+N],father[N],dep[N],cnt[N]; 16 vector<int>G[N]; 17 vector<tag>tag1[N],tag2[N]; 18 void dfs1(int x) 19 { 20 dep[x]=dep[father[x]]+1; 21 for(int i=0;i<=19;i++)fa[x][i+1]=fa[fa[x][i]][i]; 22 int sz=G[x].size(); 23 for(int i=0;i<sz;i++) 24 { 25 if(G[x][i]==father[x])continue; 26 father[G[x][i]]=fa[G[x][i]][0]=x; 27 dfs1(G[x][i]); 28 } 29 } 30 int lca(int x,int y) 31 { 32 if(dep[x]<dep[y])swap(x,y); 33 for(int i=20;i>=0;i--) 34 { 35 if(dep[fa[x][i]]>=dep[y])x=fa[x][i]; 36 if(x==y)return x; 37 } 38 for(int i=20;i>=0;i--) 39 { 40 if(fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i]; 41 } 42 return fa[x][0]; 43 } 44 void dfs(int x,int a,int b) 45 { 46 int sz=tag1[x].size(); 47 for(int i=0;i<sz;i++)T1[tag1[x][i].v+N]+=tag1[x][i].siz; 48 sz=tag2[x].size(); 49 for(int i=0;i<sz;i++)T2[tag2[x][i].v+N]+=tag2[x][i].siz; 50 sz=G[x].size(); 51 for(int i=0;i<sz;i++) 52 { 53 if(G[x][i]==father[x])continue; 54 dfs(G[x][i],T1[w[G[x][i]]+dep[G[x][i]]+N],T2[w[G[x][i]]-dep[G[x][i]]+N]); 55 } 56 cnt[x]+=T1[w[x]+dep[x]+N]+T2[w[x]-dep[x]+N]-a-b; 57 } 58 int main() 59 { 60 n=read();m=read(); 61 for(int x,y,i=1;i<n;i++) 62 { 63 x=read();y=read(); 64 G[x].push_back(y); 65 G[y].push_back(x); 66 } 67 for(int i=1;i<=n;i++)w[i]=read(); 68 dfs1(1); 69 for(int i=1;i<=m;i++)s[i]=read(),t[i]=read(),LCA[i]=lca(s[i],t[i]); 70 for(int i=1;i<=m;i++) 71 { 72 if(w[LCA[i]]+dep[LCA[i]]==dep[s[i]])--cnt[LCA[i]]; 73 tag1[s[i]].push_back((tag){dep[s[i]],1}); 74 tag1[father[LCA[i]]].push_back((tag){dep[s[i]],-1}); 75 tag2[t[i]].push_back((tag){dep[s[i]]-2*dep[LCA[i]],1}); 76 tag2[father[LCA[i]]].push_back((tag){dep[s[i]]-2*dep[LCA[i]],-1}); 77 } 78 dfs(1,0,0); 79 for(int i=1;i<=n;i++)printf("%d ",cnt[i]); 80 return 0; 81 } 82 //up:dep[s]=w[i]+dep[i]; 83 //down:dis(s,t)-(dep[t]-dep[i])=w[i]; 84 //=>dep[s]+dep[t]-2*dep[lca(s,t)]-dep[t]+dep[i]=w[i]; 85 //=>dep[s]-2*dep[lca(s,t)]=w[i]-dep[i]