【9018:2221】[伪模板]可持久化线段树
2221: [伪模板]可持久化线段树
时间限制: 1 Sec 内存限制: 130 MB提交: 29 解决: 11
[提交][状态][讨论版]
题目描述
小Z有一棵树,其名曰“可持久化线段树”,这棵树上有n个节点,每个节点有个权值,每1s,每个节点就会长出一个美味度为权值的果子,但是每个节点最多只会有一个果子,现在小Z打算花q秒的时间摘果子,他1s可以摘1个果子,每次摘的果子为两个点最简路径上的美味度第k小的果子,请你回答他的询问。
输入
第1行1个正整数n。
接下来n-1行,每行2个数x,y表示x、y间有边相连;
接下来1行,n个整数,表示每个节点的权值vi;
接下来1行,1个正整数q.
接下来q行,每行3个整数x,y,k表示,这1s,他摘得是x,y最简路径上的第k小。
输出
输出q行,每行1个整数表示答案。
样例输入
8
1 2
1 3
1 4
4 8
2 5
2 6
2 7
3 5 2 4 1 8 3 6
9
5 7 2
6 3 3
7 8 5
3 2 2
2 4 3
1 8 2
1 8 1
1 8 3
2 3 3
样例输出
3
5
6
3
5
4
3
6
5
提示
1<=n,q<=200000 1<=x,y,vi<=n 保证数据合法(是一棵树,且第k小存在)
题解:树上的主席树,答案为f[fa[lca(x,y)]]+f[lca(x,y)]-f[x]-f[y],注意数值可能重复。
代码如下:
1 #include<cstdio> 2 #include<iostream> 3 #define MN 200005 4 #define MM 5000005 5 using namespace std; 6 int n,m,v[MN],ct,h[MN],cnt,ls[MM],rs[MM],T[MM],rt[MM]; 7 int mn=0x7fffffff,mx=-1,dep[MN],fa[MN],sz[MN],son[MN],top[MN]; 8 struct node{int to,nxt;}e[2*MN]; 9 void ins(int u,int v){e[++ct].to=v;e[ct].nxt=h[u];h[u]=ct;} 10 void update(int &k,int l,int r,int ad){ 11 ls[++cnt]=ls[k],rs[cnt]=rs[k],T[cnt]=T[k],k=cnt; 12 if(l==r){T[k]++;return;} 13 int mid=(l+r)>>1; 14 if(ad<=mid) update(ls[k],l,mid,ad); 15 else update(rs[k],mid+1,r,ad); 16 T[k]=T[ls[k]]+T[rs[k]]; 17 } 18 int que(int k,int l,int r,int qll,int qlr,int qrl,int qrr){ 19 if(l==r) return l; 20 int mid=(l+r)>>1; 21 if(k<=T[ls[qrr]]+T[ls[qrl]]-T[ls[qll]]-T[ls[qlr]]) return que(k,l,mid,ls[qll],ls[qlr],ls[qrl],ls[qrr]); 22 else return que(k-=T[ls[qrr]]+T[ls[qrl]]-T[ls[qll]]-T[ls[qlr]],mid+1,r,rs[qll],rs[qlr],rs[qrl],rs[qrr]); 23 } 24 void dfs1(int u,int f,int d){ 25 dep[u]=d,fa[u]=f,sz[u]=1; 26 rt[u]=rt[f],update(rt[u],mn,mx,v[u]); 27 for(int i=h[u];i;i=e[i].nxt)if(e[i].to!=f){ 28 dfs1(e[i].to,u,d+1); sz[u]+=sz[e[i].to]; 29 if(sz[e[i].to]>sz[son[u]]) son[u]=e[i].to; 30 } 31 } 32 void dfs2(int u,int tp){ 33 top[u]=tp; if(son[u]) dfs2(son[u],tp); 34 for(int i=h[u];i;i=e[i].nxt) 35 if(e[i].to!=fa[u]&&e[i].to!=son[u]) dfs2(e[i].to,e[i].to); 36 } 37 int lca(int x,int y){ 38 while(top[x]!=top[y]) 39 if(dep[top[x]]>dep[top[y]]) x=fa[top[x]]; 40 else y=fa[top[y]]; 41 return dep[x]>dep[y]?y:x; 42 } 43 int main() 44 { 45 scanf("%d",&n); 46 for(int i=1;i<n;i++){ 47 int x,y; scanf("%d%d",&x,&y); 48 ins(x,y); ins(y,x); 49 } 50 for(int i=1;i<=n;i++){ 51 scanf("%d",&v[i]); 52 mx=max(mx,v[i]); mn=min(mn,v[i]); 53 } 54 dfs1(1,0,1); dfs2(1,1); 55 scanf("%d",&m); 56 for(int i=1;i<=m;i++){ 57 int x,y,z; scanf("%d%d%d",&x,&y,&z); 58 int tmp=lca(x,y); 59 printf("%d\n",que(z,mn,mx,rt[fa[tmp]],rt[tmp],rt[x],rt[y])); 60 } 61 }