[bzoj3551] Peaks加强版
Kruskal重构树。轻微卡常。
- 代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+5;
const int M=1e6+5;
struct edge{
int u,v,val;
bool operator<(const edge b)const{return val<b.val;}
}e[M];
int n,m,q;
int hh[N],linker[N],fa[N],par[N];
int findlink(int x){return linker[x]==x?x:linker[x]=findlink(linker[x]);}
int findpar(int x){return par[x]==x?par[x]:par[x]=findpar(par[x]);}
int anc[N][20],mx[N][20],val[N];
int root,ch[N][2],num,id[N],rt[N];
int ll[N],rr[N];
struct SegT{
int lch[N*12],rch[N*12],t[N*12],cnt;
inline void ins(int &x,int pst,int l,int r,int pos,int sum){
if(!x)x=++cnt;
int mid=(l+r)>>1;
t[x]=t[pst]+sum;
if(l==r){return;}
if(pos>mid)ins(rch[x],rch[pst],mid+1,r,pos,sum),lch[x]=lch[pst];
else ins(lch[x],lch[pst],l,mid,pos,sum),rch[x]=rch[pst];
}
inline int qry(int x,int y,int l,int r,int sum){
int tx=t[x]-t[y];
int mid=(l+r)>>1;
if(sum>tx)return -1;
if(l==r)return l;
if(t[rch[x]]-t[rch[y]]>=sum)
return qry(rch[x],rch[y],mid+1,r,sum);
else
return qry(lch[x],lch[y],l,mid,sum-(t[rch[x]]-t[rch[y]]));
}
}T;
inline void dfs(int x){
if(x<=n){
ll[x]=rr[x]=num+1;
id[x]=++num;
T.ins(rt[num],rt[num-1],1,n,hh[x],1);
return ;
}
dfs(ch[x][0]);
dfs(ch[x][1]);
ll[x]=ll[ch[x][0]];
rr[x]=rr[ch[x][1]];
}
typedef pair<int,int> pii;
int read(){
char x=0;int ret=0;
while(x<'0'||x>'9')x=getchar();
while(x>='0'&&x<='9')ret=ret*10+x-'0',x=getchar();
return ret;
}
pii rk[N];
int main()
{
n=read(),m=read(),q=read();
root=n;
for(int i=1;i<=n;i++){
hh[i]=read();
rk[i]=pii(hh[i],i);
}
sort(rk+1,rk+n+1);
for(int i=1;i<=n;i++){
hh[rk[i].second]=i;
}
for(int i=1;i<=m;i++){
e[i].u=read(),e[i].v=read(),e[i].val=read();
}
for(int i=1;i<=n*2+2;i++)linker[i]=i,par[i]=i;
sort(e+1,e+m+1);
for(int i=1;i<=m;i++){
int u=e[i].u,v=e[i].v;
int x=findlink(u),y=findlink(v);
if(x^y){
linker[x]=y;
int uu=findpar(u),vv=findpar(v);
++root;
val[root]=e[i].val;
par[uu]=par[vv]=root;
fa[uu]=fa[vv]=root;
ch[root][0]=uu;ch[root][1]=vv;
}
}
dfs(root);
for(int i=1;i<=root;i++){
anc[i][0]=fa[i];
mx[i][0]=val[fa[i]];
}
int tp=1;
for(int i=1;1<<i<=root;i++){
tp=i;
for(int j=1;j<=root;j++){
anc[j][i]=anc[anc[j][i-1]][i-1];
}
}
int lastans=0;
while(q--){
int v,x,k;
v=read(),x=read(),k=read();
v^=lastans,x^=lastans,k^=lastans;
for(int i=tp;~i;i--){
if(anc[v][i]){
if(val[anc[v][i]]<=x){
v=anc[v][i];
}
}
}
int ans=T.qry(rt[rr[v]],rt[ll[v]-1],1,n,k);
if(ans!=-1)ans=rk[ans].first;
printf("%d\n",ans);
if(ans==-1)ans=0;
lastans=ans;
}
}