[NOIP 2016D2T2/Luogu P1600] 天天爱跑步 (LCA+差分)
待填坑
Code
//Luogu P1600 天天爱跑步 //Apr,4th,2018 //树上差分+LCA #include<iostream> #include<cstdio> #include<vector> using namespace std; long long read() { long long x=0,f=1; char c=getchar(); while(!isdigit(c)){if(c=='-') f=-1;c=getchar();} while(isdigit(c)){x=x*10+c-'0';c=getchar();} return x*f; } const int N=300000+100; vector <int> e[N]; int n,m; int fa[N][21],depth[N],T[N]; void dfs(int now) { for(int i=1;i<=20;i++) fa[now][i]=fa[fa[now][i-1]][i-1]; for(int i=0;i<int(e[now].size());i++) if(depth[e[now][i]]==0) { depth[e[now][i]]=depth[now]+1; fa[e[now][i]][0]=now; dfs(e[now][i]); } } int LCA(int x,int y) { if(depth[x]<depth[y]) swap(x,y); for(int i=20;i>=0;i--) if(depth[fa[x][i]]>=depth[y]) x=fa[x][i]; if(x==y) return x; for(int i=20;i>=0;i--) if(fa[x][i]!=fa[y][i]) x=fa[x][i],y=fa[y][i]; return fa[x][0]; } struct mark { int count,num; }; vector <mark> mk1[N],mk2[N]; int ans[N],MK1[N*10],MK2[N*10]; void dfs2(int now) { int rec1=MK1[T[now]+depth[now]],rec2=MK2[T[now]-depth[now]+2*N]; for(int i=0;i<int(e[now].size());i++) if(depth[e[now][i]]>depth[now]) dfs2(e[now][i]); for(int i=0;i<int(mk1[now].size());i++) MK1[mk1[now][i].num]+=mk1[now][i].count; for(int i=0;i<int(mk2[now].size());i++) MK2[mk2[now][i].num]+=mk2[now][i].count; ans[now]+=MK1[T[now]+depth[now]]-rec1; ans[now]+=MK2[T[now]-depth[now]+2*N]-rec2; } int main() { n=read(),m=read(); for(int i=1;i<=n;i++) e[i].reserve(4); for(int i=1;i<n;i++) { int s=read(),t=read(); e[s].push_back(t); e[t].push_back(s); } for(int i=1;i<=n;i++) T[i]=read(); depth[1]=1; dfs(1); for(int i=1;i<=m;i++) { int s=read(),t=read(),lca=LCA(s,t); mk1[s].push_back((mark){1,depth[s]}); mk2[t].push_back((mark){1,depth[s]-2*depth[lca]+2*N}); mk1[lca].push_back((mark){-1,depth[s]}); mk2[fa[lca][0]].push_back((mark){-1,depth[s]-2*depth[lca]+2*N}); } dfs2(1); for(int i=1;i<=n;i++) printf("%d ",ans[i]); return 0; }
自己选择的路,跪着也要走完。朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。