5 条题解
-
2你们的爸爸 LV 9 @ 2018-10-14 18:48:15
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<algorithm> #define N 300009 #define M 600009 using namespace std; int en,n,m; int w[N],spn[M],bucket[N+M],ans[N]; vector<int> v1[M],v2[M],v3[M]; struct nod{ int u,v,dis,lca; }p[N]; struct edge{ int e; edge *next; }*v[N],ed[M]; inline void add_edge(int s,int e){ en++; ed[en].next = v[s],v[s] = ed+en,v[s]->e =e; } int read(){ int x = 0; char ch = getchar(); while(ch < '0' || ch > '9')ch = getchar(); while(ch >= '0' && ch <= '9'){ x = x * 10 + ch - '0'; ch = getchar(); } return x; } int deep[N],f[N][25],dist[N]; bool use[N]; void dfs(int now,int dep){ use[now] = true; deep[now] = dep; for(int k = 1;k <= 22; k++){ int j = f[now][k-1]; f[now][k] = f[j][k-1]; } for(edge *e = v[now];e;e=e->next) if(!use[e->e]){ f[e->e][0] = now; dist[e->e] = dist[now]+1; dfs(e->e,dep+1); } use[now] = false; } inline int jump(int u,int step){ for(int k = 0; k <= 22; k++) if((step & (1<<k)))u = f[u][k]; return u; } inline int qlca(int u,int v){ if(deep[u] < deep[v])swap(u,v); u = jump(u,deep[u]-deep[v]); for(int k = 22; k >= 0; k--) if(f[u][k] != f[v][k])u = f[u][k],v = f[v][k]; return u == v ? u : f[u][0]; } void LCA(){ //关于LCA的组件 f[1][0] = 1; dfs(1,0); } inline void dfs1(int now){ use[now] = true; int prev = bucket[deep[now]+w[now]+N]; for(edge *e = v[now];e;e=e->next) if(!use[e->e])dfs1(e->e); bucket[deep[now]+N] += spn[now]; ans[now] += bucket[deep[now]+w[now]+N]-prev; int len = v1[now].size(); for(int k = 0; k < len;k++) --bucket[deep[v1[now][k]]+N]; use[now] = false; } inline void dfs2(int now){ use[now] = true; int prev = bucket[w[now]-deep[now]+N]; for(edge *e = v[now];e;e=e->next) if(!use[e->e])dfs2(e->e); int len = v2[now].size(); for(int k = 0; k < len; k++) ++bucket[v2[now][k]+N]; ans[now] += bucket[w[now]-deep[now]+N] - prev; len = v3[now].size(); for(int k = 0; k < len; k++) --bucket[v3[now][k]+N]; use[now] = false; } int main(){ n = read(),m = read(); for(int i = 1; i <= n-1; i++){ int u = read(), v = read(); add_edge(u,v); add_edge(v,u); } for(int i = 1; i <= n; i++)w[i] = read(); LCA(); for(int i = 1; i <= m; i++){ //预处理 int u = read(),v = read(); p[i].u = u; p[i].v = v; p[i].lca = qlca(u,v); p[i].dis = dist[u]+dist[v]-dist[p[i].lca]*2; spn[u]++; v1[p[i].lca].push_back(u); v2[v].push_back(p[i].dis-deep[p[i].v]); v3[p[i].lca].push_back(p[i].dis-deep[p[i].v]); } dfs1(1); //从下至上 dfs2(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]); printf("\n"); return 0; }
-
02020-11-25 14:55:34@
第一個是實現算法的程序(會超時最後一個測試點),第二個是優化後的程序(AC)
#include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <vector> #include <deque> using namespace std; namespace dts { typedef unsigned int uint; const uint lgs=19; int cnt,maxdep; class tr_node { public: int fa,dep=0,size,hs,top,id=0; vector<int> s; }; int rk[(1<<lgs)+1],inrec[(1<<lgs)+1],outrec[(1<<lgs)+1]; tr_node tr[(1<<lgs)+1]; void tr_dfs1(int now,int fa) { tr[now].fa=fa; if (now>0) tr[now].dep=tr[fa].dep+1; maxdep=max(maxdep,tr[now].dep); tr[now].size=1; tr[now].hs=-1; for (int i=0;i<tr[now].s.size();i++) if (tr[now].s[i]!=fa) { int next=tr[now].s[i]; tr_dfs1(next,now); tr[now].size+=tr[next].size; if (tr[now].hs==-1) tr[now].hs=next; else if (tr[tr[now].hs].size<tr[next].size) tr[now].hs=next; } } void tr_dfs2(int now,int top) { tr[now].top=top; tr[now].id=++cnt; inrec[now]=cnt; rk[cnt]=now; if (tr[now].hs!=-1) { tr_dfs2(tr[now].hs,top); for (int i=0;i<tr[now].s.size();i++) if (tr[now].s[i]!=tr[now].fa&&tr[now].s[i]!=tr[now].hs) tr_dfs2(tr[now].s[i],tr[now].s[i]); } outrec[now]=cnt; } void tr_build(int rt) { cnt=0,maxdep=0; tr_dfs1(rt,0); tr_dfs2(rt,rt); } int lca(int x,int y) { while (tr[x].top!=tr[y].top) { if (tr[tr[x].top].dep<tr[tr[y].top].dep) swap(x,y); x=tr[tr[x].top].fa; } if (tr[x].dep<tr[y].dep) return x; else return y; } class segtree { public: int size=0; class strec { public: int rt=-1,rtl=1,rtr=-1; }; vector<strec> rec; deque<int> fa,lc,rc,sl,sr,smid,sum,sumlz; void reszcl(int rec_size) { size=0; rec.resize(rec_size); fa.clear(),lc.clear(),rc.clear(); sl.clear(),sr.clear(),smid.clear(); sum.clear(),sumlz.clear(); } void set_st(int rcp,int l,int r) { rec[rcp].rt=-1,rec[rcp].rtl=l,rec[rcp].rtr=r; } int len(int now) { return sr[now]-sl[now]+1; } void update(int rcp,int &now,int fath,int l,int r,int val) { if (now==-1||now+1>size) { now=size++; fa.push_back(fath),lc.push_back(-1),rc.push_back(-1); sum.push_back(0),sumlz.push_back(0); if (now==rec[rcp].rt) sl.push_back(rec[rcp].rtl),sr.push_back(rec[rcp].rtr); else { if (lc[fa[now]]==now) sl.push_back(sl[fa[now]]),sr.push_back(smid[fa[now]]); else if (rc[fa[now]]==now) sl.push_back(smid[fa[now]]+1),sr.push_back(sr[fa[now]]); } smid.push_back((sl[now]+sr[now])>>1); } if (sl[now]==l&&r==sr[now]) { sum[now]+=len(now)*val; sumlz[now]+=val; } else { if (sumlz[now]!=0) { update(rcp,lc[now],now,sl[now],smid[now],sumlz[now]); update(rcp,rc[now],now,smid[now]+1,sr[now],sumlz[now]); sumlz[now]=0; } if (r<=smid[now]) update(rcp,lc[now],now,l,r,val); else if (smid[now]+1<=l) update(rcp,rc[now],now,l,r,val); else update(rcp,lc[now],now,l,smid[now],val),update(rcp,rc[now],now,smid[now]+1,r,val); sum[now]=((lc[now]==-1)?0:sum[lc[now]])+((rc[now]==-1)?0:sum[rc[now]]); } } int ask(int rcp,int now,int l,int r) { if (now==-1||now+1>size) return 0; if (sl[now]==l&&r==sr[now]) return sum[now]; else { if (sumlz[now]!=0) { update(rcp,lc[now],now,sl[now],smid[now],sumlz[now]); update(rcp,rc[now],now,smid[now]+1,sr[now],sumlz[now]); sumlz[now]=0; } if (r<=smid[now]) return ask(rcp,lc[now],l,r); else if (smid[now]+1<=l) return ask(rcp,rc[now],l,r); else return ask(rcp,lc[now],l,smid[now])+ask(rcp,rc[now],smid[now]+1,r); } } }; segtree udst; int n,m,w[(1<<lgs)+1],s[(1<<lgs)+1],t[(1<<lgs)+1],ans[(1<<lgs)+1]; void main() { scanf("%d%d",&n,&m); for (int i=0;i<=n;i++) tr[i].s.clear(); tr[0].s.push_back(1); for (int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); tr[x].s.push_back(y); tr[y].s.push_back(x); } for (int i=1;i<=n;i++) scanf("%d",&w[i]); tr_build(1); for (int i=1;i<=m;i++) scanf("%d%d",&s[i],&t[i]); memset(ans,0,sizeof(ans)); udst.reszcl(n<<1|1); for (int i=0;i<=(n<<1);i++) udst.set_st(i,1,n); for (int i=1;i<=m;i++) { int lcan=lca(s[i],t[i]),nums=tr[s[i]].dep; if (tr[s[i]].id>0) udst.update(nums,udst.rec[nums].rt,-1,tr[s[i]].id,tr[s[i]].id,1); if (tr[tr[lcan].fa].id>0) udst.update(nums,udst.rec[nums].rt,-1,tr[tr[lcan].fa].id,tr[tr[lcan].fa].id,-1); } for (int i=1;i<=n;i++) { int nums=tr[i].dep+w[i]; ans[i]+=udst.ask(nums,udst.rec[nums].rt,inrec[i],outrec[i]); } udst.reszcl(n<<1|1); for (int i=0;i<=(n<<1);i++) udst.set_st(i,1,n); for (int i=1;i<=m;i++) { int lcan=lca(s[i],t[i]),numt=tr[s[i]].dep-(tr[lcan].dep<<1)+n; if (tr[t[i]].id>0) udst.update(numt,udst.rec[numt].rt,-1,tr[t[i]].id,tr[t[i]].id,1); if (tr[lcan].id>0) udst.update(numt,udst.rec[numt].rt,-1,tr[lcan].id,tr[lcan].id,-1); } for (int i=1;i<=n;i++) { int numt=w[i]-tr[i].dep+n; ans[i]+=udst.ask(numt,udst.rec[numt].rt,inrec[i],outrec[i]); } for (int i=1;i<=n;i++) printf("%d ",ans[i]); } } int main() { dts::main(); }
分割線
#include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <algorithm> #include <vector> #include <deque> using namespace std; namespace dts { typedef unsigned int uint; const uint lgs=19; int cnt,maxdep; class tr_node { public: int fa,dep=0,size,hs,top,id=0; vector<int> s; }; int rk[(1<<lgs)+1],inrec[(1<<lgs)+1],outrec[(1<<lgs)+1]; tr_node tr[(1<<lgs)+1]; void tr_dfs1(int now,int fa) { tr[now].fa=fa; if (now>0) tr[now].dep=tr[fa].dep+1; maxdep=max(maxdep,tr[now].dep); tr[now].size=1; tr[now].hs=-1; for (int i=0;i<tr[now].s.size();i++) if (tr[now].s[i]!=fa) { int next=tr[now].s[i]; tr_dfs1(next,now); tr[now].size+=tr[next].size; if (tr[now].hs==-1) tr[now].hs=next; else if (tr[tr[now].hs].size<tr[next].size) tr[now].hs=next; } } void tr_dfs2(int now,int top) { tr[now].top=top; tr[now].id=++cnt; inrec[now]=cnt; rk[cnt]=now; if (tr[now].hs!=-1) { tr_dfs2(tr[now].hs,top); for (int i=0;i<tr[now].s.size();i++) if (tr[now].s[i]!=tr[now].fa&&tr[now].s[i]!=tr[now].hs) tr_dfs2(tr[now].s[i],tr[now].s[i]); } outrec[now]=cnt; } void tr_build(int rt) { cnt=0,maxdep=0; tr_dfs1(rt,0); tr_dfs2(rt,rt); } int lca(int x,int y) { while (tr[x].top!=tr[y].top) { if (tr[tr[x].top].dep<tr[tr[y].top].dep) swap(x,y); x=tr[tr[x].top].fa; } if (tr[x].dep<tr[y].dep) return x; else return y; } class segtree { public: int size=0; class strec { public: int rt=-1,rtl=1,rtr=-1; }; vector<strec> rec; vector<int> fa,lc,rc,sl,sr,smid,sum,sumlz; //deque<int> fa,lc,rc,sl,sr,smid,sum,sumlz; void reszcl(int rec_size) { size=0; rec.resize(rec_size); /*fa.clear(),lc.clear(),rc.clear(); sl.clear(),sr.clear(),smid.clear(); sum.clear(),sumlz.clear();*/ fa.resize(rec_size<<3),lc.resize(rec_size<<3),rc.resize(rec_size<<3); sl.resize(rec_size<<3),sr.resize(rec_size<<3),smid.resize(rec_size<<3); sum.resize(rec_size<<3),sumlz.resize(rec_size<<3); } void set_st(int rcp,int l,int r) { rec[rcp].rt=-1,rec[rcp].rtl=l,rec[rcp].rtr=r; } int len(int now) { return sr[now]-sl[now]+1; } /* void update(int rcp,int &now,int fath,int l,int r,int val) { if (now==-1||now+1>size) { now=size++; fa.push_back(fath),lc.push_back(-1),rc.push_back(-1); sum.push_back(0),sumlz.push_back(0); if (now==rec[rcp].rt) sl.push_back(rec[rcp].rtl),sr.push_back(rec[rcp].rtr); else { if (lc[fa[now]]==now) sl.push_back(sl[fa[now]]),sr.push_back(smid[fa[now]]); else if (rc[fa[now]]==now) sl.push_back(smid[fa[now]]+1),sr.push_back(sr[fa[now]]); } smid.push_back((sl[now]+sr[now])>>1); } if (sl[now]==l&&r==sr[now]) { sum[now]+=len(now)*val; sumlz[now]+=val; } else { if (sumlz[now]!=0) { update(rcp,lc[now],now,sl[now],smid[now],sumlz[now]); update(rcp,rc[now],now,smid[now]+1,sr[now],sumlz[now]); sumlz[now]=0; } if (r<=smid[now]) update(rcp,lc[now],now,l,r,val); else if (smid[now]+1<=l) update(rcp,rc[now],now,l,r,val); else update(rcp,lc[now],now,l,smid[now],val),update(rcp,rc[now],now,smid[now]+1,r,val); sum[now]=((lc[now]==-1)?0:sum[lc[now]])+((rc[now]==-1)?0:sum[rc[now]]); } } */ void update(int rcp,int now,int *pnow,int fath,int l,int r,int val) { if (now==-1||now+1>size) { now=size++,*pnow=now; if (size>fa.size()) { fa.resize(size,-1),lc.resize(size,-1),rc.resize(size,-1); sl.resize(size,1),sr.resize(size,-1),smid.resize(size,0); sum.resize(size,0),sumlz.resize(size,0); } fa[now]=fath,lc[now]=rc[now]=-1; sum[now]=sumlz[now]=0; if (now==rec[rcp].rt) sl[now]=rec[rcp].rtl,sr[now]=rec[rcp].rtr; else { if (lc[fa[now]]==now) sl[now]=sl[fa[now]],sr[now]=smid[fa[now]]; else if (rc[fa[now]]==now) sl[now]=smid[fa[now]]+1,sr[now]=sr[fa[now]]; } smid[now]=(sl[now]+sr[now])>>1; } if (sl[now]==l&&r==sr[now]) { sum[now]+=len(now)*val; sumlz[now]+=val; } else { if (sumlz[now]!=0) { update(rcp,lc[now],&lc[now],now,sl[now],smid[now],sumlz[now]); update(rcp,rc[now],&rc[now],now,smid[now]+1,sr[now],sumlz[now]); sumlz[now]=0; } if (r<=smid[now]) update(rcp,lc[now],&lc[now],now,l,r,val); else if (smid[now]+1<=l) update(rcp,rc[now],&rc[now],now,l,r,val); else update(rcp,lc[now],&lc[now],now,l,smid[now],val),update(rcp,rc[now],&rc[now],now,smid[now]+1,r,val); sum[now]=((lc[now]==-1)?0:sum[lc[now]])+((rc[now]==-1)?0:sum[rc[now]]); } } int ask(int rcp,int now,int l,int r) { if (now==-1||now+1>size) return 0; if (sl[now]==l&&r==sr[now]) return sum[now]; else { if (sumlz[now]!=0) { update(rcp,lc[now],&lc[now],now,sl[now],smid[now],sumlz[now]); update(rcp,rc[now],&rc[now],now,smid[now]+1,sr[now],sumlz[now]); sumlz[now]=0; } if (r<=smid[now]) return ask(rcp,lc[now],l,r); else if (smid[now]+1<=l) return ask(rcp,rc[now],l,r); else return ask(rcp,lc[now],l,smid[now])+ask(rcp,rc[now],smid[now]+1,r); } } }; segtree udst; int n,m,w[(1<<lgs)+1],s[(1<<lgs)+1],t[(1<<lgs)+1],ans[(1<<lgs)+1]; /* void main() { scanf("%d%d",&n,&m); for (int i=0;i<=n;i++) tr[i].s.clear(); tr[0].s.push_back(1); for (int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); tr[x].s.push_back(y); tr[y].s.push_back(x); } for (int i=1;i<=n;i++) scanf("%d",&w[i]); tr_build(1); for (int i=1;i<=m;i++) scanf("%d%d",&s[i],&t[i]); memset(ans,0,sizeof(ans)); udst.reszcl(n<<1|1); for (int i=0;i<=(n<<1);i++) udst.set_st(i,1,n); for (int i=1;i<=m;i++) { int lcan=lca(s[i],t[i]),nums=tr[s[i]].dep; if (tr[s[i]].id>0) udst.update(nums,udst.rec[nums].rt,-1,tr[s[i]].id,tr[s[i]].id,1); if (tr[tr[lcan].fa].id>0) udst.update(nums,udst.rec[nums].rt,-1,tr[tr[lcan].fa].id,tr[tr[lcan].fa].id,-1); } for (int i=1;i<=n;i++) { int nums=tr[i].dep+w[i]; ans[i]+=udst.ask(nums,udst.rec[nums].rt,inrec[i],outrec[i]); } udst.reszcl(n<<1|1); for (int i=0;i<=(n<<1);i++) udst.set_st(i,1,n); for (int i=1;i<=m;i++) { int lcan=lca(s[i],t[i]),numt=tr[s[i]].dep-(tr[lcan].dep<<1)+n; if (tr[t[i]].id>0) udst.update(numt,udst.rec[numt].rt,-1,tr[t[i]].id,tr[t[i]].id,1); if (tr[lcan].id>0) udst.update(numt,udst.rec[numt].rt,-1,tr[lcan].id,tr[lcan].id,-1); } for (int i=1;i<=n;i++) { int numt=w[i]-tr[i].dep+n; ans[i]+=udst.ask(numt,udst.rec[numt].rt,inrec[i],outrec[i]); } for (int i=1;i<=n;i++) printf("%d ",ans[i]); } */ void main() { scanf("%d%d",&n,&m); for (int i=0;i<=n;i++) tr[i].s.clear(); tr[0].s.push_back(1); for (int i=1;i<n;i++) { int x,y; scanf("%d%d",&x,&y); tr[x].s.push_back(y); tr[y].s.push_back(x); } for (int i=1;i<=n;i++) scanf("%d",&w[i]); tr_build(1); for (int i=1;i<=m;i++) scanf("%d%d",&s[i],&t[i]); memset(ans,0,sizeof(ans)); udst.reszcl(n<<1|1); for (int i=0;i<=(n<<1);i++) udst.set_st(i,1,n); for (int i=1;i<=m;i++) { int lcan=lca(s[i],t[i]),nums=tr[s[i]].dep; if (tr[s[i]].id>0) udst.update(nums,udst.rec[nums].rt,&udst.rec[nums].rt,-1,tr[s[i]].id,tr[s[i]].id,1); if (tr[tr[lcan].fa].id>0) udst.update(nums,udst.rec[nums].rt,&udst.rec[nums].rt,-1,tr[tr[lcan].fa].id,tr[tr[lcan].fa].id,-1); } for (int i=1;i<=n;i++) { int nums=tr[i].dep+w[i]; ans[i]+=udst.ask(nums,udst.rec[nums].rt,inrec[i],outrec[i]); } udst.reszcl(n<<1|1); for (int i=0;i<=(n<<1);i++) udst.set_st(i,1,n); for (int i=1;i<=m;i++) { int lcan=lca(s[i],t[i]),numt=tr[s[i]].dep-(tr[lcan].dep<<1)+n; if (tr[t[i]].id>0) udst.update(numt,udst.rec[numt].rt,&udst.rec[numt].rt,-1,tr[t[i]].id,tr[t[i]].id,1); if (tr[lcan].id>0) udst.update(numt,udst.rec[numt].rt,&udst.rec[numt].rt,-1,tr[lcan].id,tr[lcan].id,-1); } for (int i=1;i<=n;i++) { int numt=w[i]-tr[i].dep+n; ans[i]+=udst.ask(numt,udst.rec[numt].rt,inrec[i],outrec[i]); } for (int i=1;i<=n;i++) printf("%d ",ans[i]); } } int main() { dts::main(); }
-
02020-11-25 00:08:23@
-
-12018-10-07 08:19:50@
-
-252017-03-04 10:03:00@
䐞䐞的六十分,但好想好做
#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
#include<stack>
#include<cmath>
using namespace std;
int n,m;
int point[100001],nex[100001],to[100001],father[100001],deep[100001];
//父节点只想的第一条边 此边的下一条边 边的指向 父节点 深度
int belong[100001],watch[100001];//属于集合 观察时间
int start;//根节点
int s[100001],t[100001],lca[100001];//每一对询问的起始点及其最近公共祖先
bool whether_father[100001],hasover[100001];//是否是父亲 此次询问是否已结束
int ans[100001];//答案
int set(int k)//求并查集的指向
{
if(belong[k]!=k)belong[k]=set(father[k]);
return belong[k];
}
int outline_targan(int p)//求LCA
{
deep[p]=deep[father[p]]+1;//记录深度
int side=point[p];
while(side!=0)//访问本点的所有子节点
{
outline_targan(to[side]);
side=nex[side];
}
for(int i=1;i<=m;i++)//寻求此对询问是否属于同一集合
{
if((hasover[i]==false)&&(set(s[i])==set(t[i])))//询问属于同一集合且未完成询问
{
lca[i]=set(t[i]);
hasover[i]=true;//标记此次询问已经被完成
}
}
belong[p]=father[p];//本点结束访问后,将自己指向父亲
return 0;
}
int main()
{
//freopen("天天爱跑步测试数据1.txt","r",stdin);
memset(hasover,false,sizeof(hasover));//所有询问尚未完成
memset(lca,0,sizeof(lca));
memset(watch,0,sizeof(watch));
memset(whether_father,true,sizeof(whether_father));
memset(point,0,sizeof(point));
memset(to,0,sizeof(to));
memset(father,0,sizeof(father));
memset(ans,0,sizeof(ans));
memset(s,0,sizeof(s));
memset(t,0,sizeof(t));
memset(deep,0,sizeof(deep));//每个节点的深度
memset(nex,0,sizeof(nex));//以上初始化
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)belong[i]=i;//并查集初始化
for(int i=1;i<=n-1;i++)//输入树
{
int u,v;
scanf("%d%d",&u,&v);
nex[i]=point[u];
point[u]=i;
father[v]=u;
to[i]=v;
whether_father[v]=false;
}
start=1;
while(whether_father[start]!=true)start++;//确定根节点
for(int i=1;i<=n;i++)//输入观察时间
scanf("%d",&watch[i]);
for(int i=1;i<=m;i++)//输入每一组询问的起始点
scanf("%d%d",&s[i],&t[i]);father[start]=start;
outline_targan(start);//离线targan求最近公共祖先for(int i=1;i<=m;i++)//处理每一组询问
{
int p=s[i],q=t[i];
if(deep[s[i]]>deep[lca[i]])
{
do
{
if(deep[s[i]]-deep[p]==watch[p])ans[p]++;
p=father[p];
}while(p!=lca[i]);//从起始点向上追溯
}
if(deep[lca[i]]-deep[s[i]]==watch[lca[i]])ans[lca[i]]++;//lca单独来 考虑
if(deep[t[i]]>deep[lca[i]])
{
do
{
if(deep[s[i]]+deep[q]-2*deep[lca[i]]==watch[q])ans[q]++;
q=father[q];
}while(q!=lca[i]);//从终点向上追溯
}
}
for(int l=1;l<=n;l++)printf("%d ",ans[l]);
return 0;
}
- 1
信息
- ID
- 2004
- 难度
- 8
- 分类
- (无)
- 标签
- 递交数
- 1681
- 已通过
- 154
- 通过率
- 9%
- 被复制
- 16
- 上传者