2 条题解
-
3
#include <bits/stdc++.h> using namespace std; const int N=200005; int n,m,k,s,t,tot,head[N],ROOT,x,y,q,dfn[N],sz[N]; int ti[N],f[N][20],log2n,de[N],tot1,tot2,tr[N]; pair<int,int> ans[N]; struct node{ int y,next; }e[N<<1]; struct node1{ int x,y,c,id; bool operator<(const node1 &k)const{ return c<k.c; } }a[N];//存放询问 struct node2{ int x,c; }b[N];//存放修改 inline void add(int s,int t){ e[++tot]={t,head[s]};head[s]=tot; } void dfs(int u,int fa){ dfn[u]=++tot;sz[u]=1; for (int i=head[u];i;i=e[i].next){ int v=e[i].y; de[v]=de[u]+1; dfs(v,u); sz[u]+=sz[v]; } } inline int lca(int x,int y){ if (de[x]<de[y]) swap(x,y); for (int k=de[x]-de[y],o=0;k;k>>=1,++o) if (k&1) x=f[x][o]; if (x==y) return x; for (int j=log2n;j>=0;--j) if (f[x][j]!=f[y][j]){ x=f[x][j]; y=f[y][j]; } return f[x][0]; } void change(int x,int k){ for (int i=x;i<=n;i+=i&(-i)) tr[i]+=k; } int query(int x){ int ans=0; for (int i=x;i;i-=i&(-i)) ans+=tr[i]; return ans; } int main(){ cin>>n; for (int i=1;i<=n;++i) { cin>>k; f[i][0]=k; if (!k) ROOT=i; else add(k,i); } cin>>q;int opt; for (int i=1;i<=q;++i){ cin>>opt; if (opt==1){//询问存放在a中 ++tot1; cin>>a[tot1].x>>a[tot1].y>>a[tot1].c; a[tot1].c=i-a[tot1].c; a[tot1].id=i; } else {//修改存放在b中 ++tot2; cin>>b[tot2].x;b[tot2].c=i; } } tot=0; dfs(ROOT,0); log2n=log2(n); for (int j=1;j<=log2n;++j) for (int i=1;i<=n;++i) f[i][j]=f[f[i][j-1]][j-1]; sort(a+1,a+1+tot1);//将询问排序 int l=1; for (int i=1;i<=tot1;++i){ while (l<=tot2 && b[l].c<a[i].c){//把所有修改时刻在询问之前的插入 int x=b[l].x; change(dfn[x],1); change(dfn[x]+sz[x],-1); ++l; } k=lca(a[i].x,a[i].y); ans[a[i].id]=make_pair(de[a[i].x]+de[a[i].y]-de[k]*2+1, query(dfn[a[i].x])+query(dfn[a[i].y])-query(dfn[k])-query(dfn[f[k][0]])); } for (int i=1;i<=n;++i) if (ans[i].first) cout<<ans[i].first<<' '<<ans[i].second<<'\n'; }
-
1
#include<cstdio> #include<cctype> #include<algorithm> #define N 200005 #define blank putchar(' ') #define nxtline putchar('\n') #define max(A,B) ((A)>(B)?(A):(B)) #define min(A,B) ((A)<(B)?(A):(B)) #define swap(A,B) ((A)^=(B)^=(A)^=(B)) int ques[N][5],q; int n,m,cnt,pos,tot; int sze[N],son[N],fa[N]; int sum[N<<2],ans[N],d[N]; int head[N],dfn[N],top[N]; struct Node{ int x,y,z; int idx,ans1,ans2; }node[N]; struct Edge{ int to,nxt; }edge[N]; void add(int x,int y){ edge[++cnt].to=y; edge[cnt].nxt=head[x]; head[x]=cnt; } bool cmp1(Node a,Node b){ return a.idx-a.z<b.idx-b.z; } bool cmp2(Node a,Node b){ return a.idx<b.idx; } int getint(){ int x=0;char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return x; } void write(int x){ if(x>9) write(x/10); putchar(x%10+'0'); } void first_dfs(int now){ sze[now]=1; for(int i=head[now];i;i=edge[i].nxt){ int to=edge[i].to; d[to]=d[now]+1; fa[to]=now; first_dfs(to); sze[now]+=sze[to]; if(sze[to]>sze[son[now]]) son[now]=to; } } void second_dfs(int now,int low){ top[now]=low; dfn[now]=++tot; if(son[now]) second_dfs(son[now],low); for(int i=head[now];i;i=edge[i].nxt){ int to=edge[i].to; if(to==son[now]) continue; second_dfs(to,to); } } void pushup(int cur){ sum[cur]=sum[cur<<1]+sum[cur<<1|1]; } void modify(int cur,int l,int r,int ql,int qr){ if(l==r){ sum[cur]=1; return; } int mid=l+r>>1; if(ql<=mid) modify(cur<<1,l,mid,ql,qr); else modify(cur<<1|1,mid+1,r,ql,qr); pushup(cur); } int query(int cur,int l,int r,int ql,int qr){ if(ql<=l and r<=qr) return sum[cur]; int mid=l+r>>1,ans=0; if(ql<=mid) ans+=query(cur<<1,l,mid,ql,qr); if(mid<qr) ans+=query(cur<<1|1,mid+1,r,ql,qr); return ans; } std::pair<int,int> ask(int x,int y){ int ans=0; while(top[x]!=top[y]){ if(d[top[x]]<d[top[y]]) swap(x,y); ans+=query(1,1,n,dfn[top[x]],dfn[x]); x=fa[top[x]]; } if(d[x]<d[y]) swap(x,y); ans+=query(1,1,n,dfn[y],dfn[x]); return std::make_pair(y,ans); } signed main(){ n=getint();int root; for(int i=1;i<=n;i++){ int p=0; if((p=getint())==0) root=i; else add(p,i); } first_dfs(root);second_dfs(root,root); m=getint(); for(int i=1;i<=m;i++){ if(getint()==1){ node[++pos].x=getint(); node[pos].y=getint(); node[pos].z=getint(); node[pos].idx=i; } else{ ques[++q][1]=getint(); ques[q][2]=i; } } std::sort(node+1,node+1+pos,cmp1); int now=0; for(int i=1;i<=pos;i++){ while(now<q and node[i].idx-node[i].z>ques[now+1][2]){ now++; modify(1,1,n,dfn[ques[now][1]],dfn[ques[now][1]]); } std::pair<int,int> p=ask(node[i].x,node[i].y); node[i].ans1=d[node[i].x]+d[node[i].y]+1-2*d[p.first]; node[i].ans2=p.second; } std::sort(node+1,node+1+pos,cmp2); for(int i=1;i<=pos;i++){ write(node[i].ans1);blank; write(node[i].ans2);nxtline; } return 0; }
- 1
信息
- ID
- 337
- 时间
- 1500ms
- 内存
- 250MiB
- 难度
- 5
- 标签
- 递交数
- 69
- 已通过
- 27
- 上传者