首先想到实际上是查询链上开始搜集的日子小于x的点的个数,然后yy了树上莫队做法。
其实这就是树上主席树的 裸题。
#include<cstdio>#include<cstdlib>#include<cstring>#include<algorithm>#define ll long long#define inf 1e9#define eps 1e-8#define md#define TR 4000010#define N 200010using namespace std;struct yts { int x,t,ne;} e[2*N];int ch[TR][2],sz[TR];int day[N],root[N],fa[N][20],v[N],X[N],Y[N],C[N],dep[N];int cnt,m,n,num,Ans=0;void put(int x,int y){num++; e[num].x=x; e[num].t=y;e[num].ne=v[x]; v[x]=num;}void insert(int &i,int pre,int l,int r,int x){i=++cnt; ch[i][0]=ch[pre][0]; ch[i][1]=ch[pre][1]; sz[i]=sz[pre]+1;if (l==r) return;int mid=(l+r)>>1;if (x<=mid) insert(ch[i][0],ch[pre][0],l,mid,x);else insert(ch[i][1],ch[pre][1],mid+1,r,x);}void query(int a,int b,int c,int d,int l,int r,int ql,int qr){if (ql<=l&&r<=qr) { Ans+=sz[a]+sz[b]-sz[c]-sz[d]; return;}int mid=(l+r)>>1;if (ql<=mid) query(ch[a][0],ch[b][0],ch[c][0],ch[d][0],l,mid,ql,qr);if (mid+1<=qr) query(ch[a][1],ch[b][1],ch[c][1],ch[d][1],mid+1,r,ql,qr);}void dfs(int x){if (day[x]) insert(root[x],root[fa[x][0]],1,m,day[x]);else root[x]=root[fa[x][0]];for (int i=v[x];i;i=e[i].ne){int y=e[i].t; dep[y]=dep[x]+1;dfs(y);}}void build_lca(){for (int j=1;j<=18;j++)for (int i=1;i<=n;i++)fa[i][j]=fa[fa[i][j-1]][j-1];}int lca(int x,int y){if (dep[x]<dep[y]) swap(x,y);int t=dep[x]-dep[y];for (int i=18;i>=0;i--)if (t&(1<<i)) x=fa[x][i];if (x==y) return x;for (int i=18;i>=0;i--)if (fa[x][i]!=fa[y][i])x=fa[x][i],y=fa[y][i];return fa[x][0];}int main(){int rt;scanf("%d",&n);for (int i=1;i<=n;i++){scanf("%d",&fa[i][0]);if (!fa[i][0]) rt=i;else put(fa[i][0],i);}scanf("%d",&m);for (int i=1;i<=m;i++){int k;scanf("%d",&k);if (k==2) { int x; scanf("%d",&x); day[x]=i;}else scanf("%d%d%d",&X[i],&Y[i],&C[i]);}dep[rt]=1; dfs(rt); build_lca();for (int i=1;i<=m;i++)if (X[i]){int z=lca(X[i],Y[i]),t=i-C[i]-1; printf("%d ",dep[X[i]]+dep[Y[i]]-2*dep[z]+1);if (t<1) printf("0\n");else{Ans=0; query(root[X[i]],root[Y[i]],root[z],root[fa[z][0]],1,m,1,t);printf("%d\n",Ans);}}return 0;}
本文介绍了一种基于树结构的主席树算法实现,并通过具体的代码示例详细讲解了其在处理特定类型查询问题上的应用。该算法适用于解决树形结构中节点间的统计查询任务。

1390

被折叠的 条评论
为什么被折叠?



