洛谷
树剖
不知道大佬们疯狂用主席树为何
#include#define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } const int maxn=200005; int n,m,fa[maxn],hd[maxn]; int k; struct node{ int to,nt; }e[maxn]; inline void add(int x,int y) { e[++k].to=y;e[k].nt=hd[x];hd[x]=k; } int deep[maxn],siz[maxn],son[maxn]; inline void dfs(int x) { siz[x]=1; for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; deep[v]=deep[x]+1; dfs(v); siz[x]+=siz[v]; if(siz[v]>siz[son[x]])son[x]=v; } } int seg[maxn],top[maxn],rev[maxn],tot; inline void dfs2(int x,int ftop) { top[x]=ftop; seg[x]=++tot; rev[tot]=x; if(son[x]) { dfs2(son[x],ftop); for(int i=hd[x];i;i=e[i].nt) { int v=e[i].to; if(!top[v]) dfs2(v,v); } } } //------------------------ #define ls rt<<1 #define rs rt<<1|1 int sum[maxn<<2]; inline void pushup(int rt) { sum[rt]=sum[ls]+sum[rs]; } inline void modify(int rt,int l,int r,int pos) { if(l==r) { sum[rt]=1; re ; } int mid=(l+r)>>1; if(pos<=mid)modify(ls,l,mid,pos); else modify(rs,mid+1,r,pos); pushup(rt); } inline int query(int rt,int l,int r,int x,int y) { if(x<=l&&r<=y) re sum[rt]; int mid=(l+r)>>1; if(y<=mid)re query(ls,l,mid,x,y); else if(x>mid)re query(rs,mid+1,r,x,y); else re query(ls,l,mid,x,y)+query(rs,mid+1,r,x,y); } struct nide{ int type,x,y,c,id; inline bool operator<(nide xx)const { if(c==xx.c)re type>xx.type; re c<xx.c; } }opt[maxn]; int ans1[maxn],ans2[maxn]; int main() { rd(n); int rt; inc(i,1,n) { rd(fa[i]); add(fa[i],i); if(!fa[i])rt=i; } dfs(rt); dfs2(rt,rt); //----- rd(m); int k,x,y,c,t; inc(i,1,m) { opt[i].id=i; rd(opt[i].type); if(opt[i].type==1) { rd(opt[i].x),rd(opt[i].y),rd(opt[i].c); opt[i].c=i-opt[i].c-1; } else rd(opt[i].x),opt[i].c=i; } sort(opt+1,opt+m+1); inc(i,1,m) { if(opt[i].type==1) { x=opt[i].x,y=opt[i].y; while(top[x]!=top[y]) { if(deep[top[x]]<deep[top[y]])swap(x,y); ans2[opt[i].id]+=query(1,1,n,seg[top[x]],seg[x]); x=fa[top[x]]; } if(deep[x]>deep[y])swap(x,y); ans1[opt[i].id]=deep[opt[i].x]+deep[opt[i].y]-deep[x]-deep[x]+1; ans2[opt[i].id]+=query(1,1,n,seg[x],seg[y]); } else modify(1,1,n,seg[opt[i].x]); } inc(i,1,m) if(ans1[i]) printf("%d %d\n",ans1[i],ans2[i]); re 0; }