[bzoj3551]Peaks加强版

kruskal重构树,求出最小生成树,然后不断加边并新建节点作为两个联通块原根节点的父亲节点并作为新联通块的根(类似于不路径压缩的并查集),这样一来满足每一个节点所代表的边(除叶子节点外)父亲总时比儿子大,因此询问即在该重构树上的某一段点的第K大,用可持久化线段树维护,同时还要用倍增来确定该段的根节点。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 200005
 4 #define mid (l+r>>1)
 5 struct ji{
 6     int x,y,z;
 7     bool operator < (const ji &a)const{
 8         return z<a.z;
 9     }
10 }a[5*N];
11 int V,n,m,q,x,y,z,ans,r[N],id[N],ls[N],rs[N],ff[N],h[N],ma[N][21],f[N][21],tr[N*20],ch[N*20][2];
12 int find(int k){
13     if (k==ff[k])return k;
14     return ff[k]=find(ff[k]);
15 }
16 void up(int k){
17     tr[k]=tr[ch[k][0]]+tr[ch[k][1]];
18 }
19 void dfs(int k){
20     for(int i=1;i<=20;i++){
21         f[k][i]=f[f[k][i-1]][i-1];
22         ma[k][i]=max(ma[k][i-1],ma[f[k][i-1]][i-1]);
23     }
24     if (!ls[k]){
25         ls[k]=rs[k]=++id[0];
26         id[id[0]]=k;
27         return;
28     }
29     dfs(ls[k]);
30     ls[k]=ls[ls[k]];
31     dfs(rs[k]);
32     rs[k]=rs[rs[k]];
33 }
34 int find(int k,int x){
35     for(int i=20;i>=0;i--)
36         if (ma[k][i]<=x)k=f[k][i];
37     return k;
38 }
39 void update(int k1,int &k2,int l,int r,int x){
40     k2=++V;
41     if (l==r){
42         tr[k2]=tr[k1]+1;
43         return;
44     }
45     memcpy(ch[k2],ch[k1],8);
46     if (x<=mid)update(ch[k1][0],ch[k2][0],l,mid,x);
47     else update(ch[k1][1],ch[k2][1],mid+1,r,x);
48     up(k2);
49 }
50 int query(int k1,int k2,int l,int r,int x){
51     if (l==r)return l;
52     int p=tr[ch[k2][1]]-tr[ch[k1][1]];
53     if (p<x)return query(ch[k1][0],ch[k2][0],l,mid,x-p);
54     return query(ch[k1][1],ch[k2][1],mid+1,r,x);
55 }
56 int main(){
57     scanf("%d%d%d",&n,&m,&q);
58     for(int i=1;i<=n;i++)scanf("%d",&h[i]);
59     for(int i=1;i<=m;i++)scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
60     sort(a+1,a+m+1);
61     for(int i=1;i<2*n;i++)ff[i]=i;
62     for(int i=1;i<=m;i++){
63         x=find(a[i].x);
64         y=find(a[i].y);
65         if (x==y)continue;
66         ff[x]=ff[y]=f[x][0]=f[y][0]=++n;
67         ma[x][0]=ma[y][0]=a[i].z;
68         ls[n]=x;
69         rs[n]=y;
70     }
71     f[n][0]=n;
72     dfs(n);
73     for(int i=1;i<=n/2+1;i++)update(r[i-1],r[i],0,1e9,h[id[i]]);
74     for(int i=1;i<=q;i++){
75         scanf("%d%d%d",&x,&y,&z);
76         x=find(x^ans,y^ans);
77         z^=ans;
78         ans=0;
79         if (tr[r[rs[x]]]-tr[r[ls[x]-1]]<z)printf("-1\n");
80         else printf("%d\n",ans=query(r[ls[x]-1],r[rs[x]],0,1e9,z));
81     }
82 }
View Code

 

posted @ 2019-11-11 14:25  PYWBKTDA  阅读(107)  评论(0编辑  收藏  举报