bzoj 3551: [ONTAK2010]Peaks加强版
这道题用到了Kruskal重构树,有个性质是这棵树是一个大根堆,而且每个点所能延伸出去的联通块在树的dfs序中是连续的一段,所以就可以用主席树维护了。
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #define N 200005 6 #define M 500005 7 #define ls a[x].l,a[y].l,l,mid 8 #define rs a[x].r,a[y].r,mid+1,r 9 using namespace std; 10 int n,m,q; 11 int v[N]; 12 struct node 13 { 14 int x,y,z; 15 friend bool operator < (node aa,node bb) 16 { 17 return aa.z<bb.z; 18 } 19 }b[M]; 20 int f[N+M]; 21 int find(int x) 22 { 23 if(x==f[x])return x; 24 return f[x]=find(f[x]); 25 } 26 int head[M],ver[M],nxt[M],tot; 27 void add(int aa,int bb) 28 { 29 tot++;nxt[tot]=head[aa];head[aa]=tot;ver[tot]=bb;return ; 30 } 31 bool vis[M]; 32 int st[N],ed[N],z; 33 int fa[N][18],mx[N][18]; 34 int d[N],jian[N]; 35 void dfs(int x,int ff) 36 { 37 vis[x]=1;st[x]=z+1; 38 if(!head[x]) 39 { 40 z++;jian[z]=v[x]; 41 } 42 for(int i=head[x];i;i=nxt[i]) 43 { 44 if(ver[i]==ff)continue; 45 fa[ver[i]][0]=x; 46 mx[ver[i]][0]=max(d[ver[i]],d[x]); 47 dfs(ver[i],x); 48 } 49 ed[x]=z; 50 } 51 int num; 52 void yu() 53 { 54 for(int i=1;i<=17;i++) 55 { 56 for(int j=1;j<=num;j++) 57 { 58 fa[j][i]=fa[fa[j][i-1]][i-1]; 59 mx[j][i]=max(mx[j][i-1],mx[fa[j][i-1]][i-1]); 60 } 61 }return ; 62 } 63 int root[N]; 64 struct ndode 65 { 66 int l,r,sum; 67 }a[4000005];int cnt; 68 void merge(int x,int y,int l,int r,int pos,int z) 69 { 70 if(l==r) 71 { 72 a[x].sum=a[y].sum+z; 73 return ; 74 } 75 int mid=(l+r)>>1; 76 if(pos<=mid) 77 { 78 a[x].l=++cnt; 79 a[x].r=a[y].r; 80 merge(ls,pos,z); 81 } 82 else 83 { 84 a[x].r=++cnt; 85 a[x].l=a[y].l; 86 merge(rs,pos,z); 87 } 88 a[x].sum=a[a[x].l].sum+a[a[x].r].sum; 89 } 90 int qur(int x,int y,int l,int r,int k) 91 { 92 if(l==r)return l; 93 if(a[x].sum-a[y].sum<k)return -1; 94 int ss=a[a[x].r].sum-a[a[y].r].sum; 95 int mid=(l+r)>>1; 96 if(ss>=k)return qur(rs,k); 97 else return qur(ls,k-ss); 98 } 99 int li[N];int cr; 100 int main() 101 { 102 scanf("%d%d%d",&n,&m,&q); 103 for(int i=1;i<=n;i++) 104 { 105 scanf("%d",&v[i]); 106 li[i]=v[i]; 107 d[i]=0; 108 }cr=n; 109 sort(li+1,li+cr+1); 110 cr=unique(li+1,li+cr+1)-li-1; 111 for(int i=1;i<=n;i++) 112 { 113 v[i]=lower_bound(li+1,li+cr+1,v[i])-li; 114 } 115 for(int i=1;i<=m;i++) 116 { 117 scanf("%d%d%d",&b[i].x,&b[i].y,&b[i].z); 118 } 119 sort(b+1,b+m+1); 120 for(int i=1;i<=n+m;i++)f[i]=i; 121 num=n; 122 for(int i=1;i<=m;i++) 123 { 124 int aa=find(b[i].x),bb=find(b[i].y); 125 if(aa!=bb) 126 { 127 num++; 128 d[num]=b[i].z; 129 f[aa]=num;f[bb]=num; 130 add(num,aa);add(num,bb); 131 } 132 } 133 for(int i=1;i<=n;i++) 134 { 135 if(!vis[i]) 136 { 137 int tt=find(i); 138 fa[tt][0]=tt;mx[tt][0]=d[tt]; 139 dfs(tt,-1); 140 } 141 } 142 yu(); 143 for(int i=1;i<=n;i++) 144 { 145 root[i]=++cnt; 146 merge(root[i],root[i-1],1,cr,jian[i],1); 147 } 148 int las=-1; 149 int t1,t2,t3; 150 for(int i=1;i<=q;i++) 151 { 152 scanf("%d%d%d",&t1,&t2,&t3); 153 if(las!=-1) 154 { 155 t1^=las;t2^=las;t3^=las; 156 } 157 int now=t1; 158 for(int j=17;j>=0;j--) 159 { 160 if(mx[now][j]<=t2)now=fa[now][j]; 161 } 162 las=qur(root[ed[now]],root[st[now]-1],1,cr,t3); 163 if(las!=-1)las=li[las]; 164 printf("%d\n",las); 165 } 166 return 0; 167 }