终于调完了,了了自己的一个心结。
并没有结束
暂时不写题解,下面的代码应该还有优化的空间,各种意义上
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
inline void read(int &res){
static char ch;int flag=1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;
while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;
}
const int N = 300000;
int n,m,deep[N],sz[N],top[N],fa[N],son[N];
int w[N],tot,cnt,cun,depth,sum[N],T[N],Z[N<<1],ans[N];
vector<int> E[N],L[N],M[N],Y[N];
struct preson{
int u,v,lca,len;
}P[N];
void dfsf(int u){
sz[u]=1;
for(int v,i=0;i<E[u].size();++i)
if(v=E[u][i],v!=fa[u]){
deep[v]=deep[u]+1;fa[v]=u;
dfsf(v),sz[u]+=sz[v];
if(sz[son[u]]<sz[v])son[u]=v;
}
}
void dfss(int u,int f){
top[u]=f;
if(son[u])dfss(son[u],f);
for(int v,i=0;i<E[u].size();++i)
if(v=E[u][i],v!=fa[u]&&v!=son[u])dfss(v,v);
}
void dfst(int u){
int dt=deep[u]+w[u],cmd;
if(dt<=depth)cmd=T[dt];
for(int v,i=0;i<E[u].size();++i)
if(v=E[u][i],v!=fa[u])dfst(v);
T[deep[u]]+=sum[u];if(dt<=depth)ans[u]=T[dt]-cmd;
for(int i=0;i<L[u].size();++i)
T[deep[L[u][i]]]--;
}
void dfsw(int u){
int dt=deep[u]-w[u]+300000,cmd;
cmd=Z[dt];
for(int v,i=0;i<E[u].size();++i)
if(v=E[u][i],v!=fa[u])dfsw(v);
for(int i=0;i<M[u].size();++i)Z[300000+M[u][i]]++;
ans[u]+=Z[dt]-cmd;
for(int i=0;i<Y[u].size();++i)Z[300000+Y[u][i]]--;
}
int lca(int x,int y){
while(top[x]!=top[y]){
if(deep[top[x]]>deep[top[y]])swap(x,y);
y=fa[top[y]];
}
return deep[x]<deep[y]?x:y;
}
int main(){
read(n),read(m);
for(int x,y,i=1;i<n;i++)
read(x),read(y),E[x].push_back(y),E[y].push_back(x);
deep[1]=1,dfsf(1),dfss(1,1);
for(int i=1;i<=n;i++)read(w[i]),depth=max(depth,deep[i]);
for(int i=1;i<=m;++i){
read(P[i].u),read(P[i].v),sum[P[i].u]++;
P[i].lca=lca(P[i].u,P[i].v),
P[i].len=deep[P[i].u]+deep[P[i].v]-deep[P[i].lca]*2;
L[P[i].lca].push_back(P[i].u);
}
dfst(1);
for(int i=1;i<=m;i++)
M[P[i].v].push_back(deep[P[i].v]-P[i].len),
Y[P[i].lca].push_back(deep[P[i].v]-P[i].len);
dfsw(1);
for(int i=1;i<=m;i++)
if(deep[P[i].u]-deep[P[i].lca]==w[P[i].lca])ans[P[i].lca]--;
for(int i=1;i<=n;i++)printf("%d ",ans[i]);
return 0;
}
更新——更加优秀的代码。。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<vector>
using namespace std;
inline void read(int &res){
static char ch;int flag=1;
while((ch=getchar())<'0'||ch>'9')if(ch=='-')flag=-1;res=ch-48;
while((ch=getchar())>='0'&&ch<='9')res=res*10+ch-48;res*=flag;
}
const int N = 300000;
int n,m,deep[N],sz[N],top[N],fa[N],son[N],cnt1[N],cnt2[N],f1[N<<1],f2[N<<1];
int w[N],sum[N],T[N],Z[N<<1],ans[N];
vector<int> E[N],L[N],M[N];
void dfsf(int u){
sz[u]=1;
for(int v,i=0;i<E[u].size();++i)
if(v=E[u][i],v!=fa[u]){
deep[v]=deep[u]+1;fa[v]=u;
dfsf(v),sz[u]+=sz[v];
if(sz[son[u]]<sz[v])son[u]=v;
}
}
void dfss(int u,int f){
top[u]=f;
if(son[u])dfss(son[u],f);
for(int v,i=0;i<E[u].size();++i)
if(v=E[u][i],v!=fa[u]&&v!=son[u])dfss(v,v);
}
void insert(int u){
for(int i=0;i<L[u].size();i++)
if (!M[u][i]){
cnt1[f1[L[u][i]-deep[u]+N]]--;
cnt2[f2[L[u][i]+deep[u]]]--;
}
else if (M[u][i]==1)cnt2[f2[L[u][i]]]++;
else cnt1[f1[L[u][i]+N]]++;
}
void dfst(int x){
int d1=w[x]-deep[x]+N,d2=w[x]+deep[x],y=f1[d1],z=f2[d2];
f1[d1]=f2[d2]=x;
for(int i=0;i<E[x].size();++i)
if(E[x][i]!=fa[x])dfst(E[x][i]);
insert(x);
ans[x]+=cnt1[x]+cnt2[x];
cnt1[y]+=cnt1[x],cnt2[z]+=cnt2[x];
f1[d1]=y;f2[d2]=z;
}
int lca(int x,int y){
while(top[x]!=top[y]){
if(deep[top[x]]>deep[top[y]])swap(x,y);
y=fa[top[y]];
}
return deep[x]<deep[y]?x:y;
}
int main(){
read(n),read(m);
for(int x,y,i=1;i<n;i++)
read(x),read(y),E[x].push_back(y),E[y].push_back(x);
deep[1]=1,fa[1]=1,dfsf(1),dfss(1,1);
for(int i=1;i<=n;i++)read(w[i]);
for(int u,v,c,i=1;i<=m;++i){
read(u),read(v),c=lca(u,v);
if(deep[u]-deep[c]==w[c])ans[c]++;
L[c].push_back(deep[u]-deep[c]),M[c].push_back(0);
L[u].push_back(deep[u]),M[u].push_back(1);
L[v].push_back((deep[u]-2*deep[c])),M[v].push_back(-1);
}
dfst(1);
for(int i=1;i<=n;i++)printf("%d ",ans[i]);
return 0;
}