最大边最小,就是最小生成树,可以考虑用主席树维护father数组,但不能遍历子集查找
然后就只能牺牲一部分空间时间来多存一些东西
多存的就是边值大小顺序,本来以为是用主席树排边值,结果由于此题有2种数据(边值、点值)要排,所以每加一个边维护点值排序空间是不对的
然后就按照边重构一棵树,尽量利用以前的结果,由于主席树类似桶排,利于合并,所以就直接指针指过去就可以了
就是在原来并查集合并的基础上,让边可持久化,用边的大小调整选用的集合
这样一个边值的一个块就在一个子树里了
然后就是子树第K大
码:
#include<bits/stdc++.h>
using namespace std;
int fu[500005],f[200005][25],qian[200005],cnt,sz[200005*20],ch[200005*20][2],i,lin[500005],tot,co[200005],a,b,v[500005],m,q,rt[200005],c,lrt[200005],last,ans,n,k,vv,x;
map<int,int>ma;
vector<int>xia[200005];
struct la
{
int a,b,v;
}B[500005];
bool cmp(la a,la b)
{
return a.v<b.v;
}
int zhao(int o)
{
if(fu[o]!=o)fu[o]=zhao(fu[o]);
return fu[o];
}
void dfs(int o)
{
int i;
for(i=1;i<=20;i++)
f[o][i]=f[f[o][i-1]][i-1];
for(i=0;i<xia[o].size();i++)
{
dfs(xia[o][i]);
}
}
void up(int o)
{
sz[o]=sz[ch[o][0]]+sz[ch[o][1]];
}
void jia(int o,int last,int l,int r)
{
if(l==r)
{
sz[o]=sz[last]+1;
return ;
}
int mid=(l+r)>>1;
if(a<=mid){
ch[o][0]=++cnt;
ch[o][1]=ch[last][1];
jia(ch[o][0],ch[last][0],l,mid);
}
if(b>mid)
{
ch[o][0]=ch[last][0];
ch[o][1]=++cnt;
jia(ch[o][1],ch[last][1],mid+1,r);
}
up(o);
}
void dfs2(int o)
{
int i;
a=b=ma[v[o]];
rt[o]=++cnt;
qian[o]=last;
jia(rt[o],last,1,n);
last=rt[o];
for(i=0;i<xia[o].size();i++)
{
int nd=xia[o][i];
dfs2(nd);
}
lrt[o]=last;
}
void cha(int o,int last,int l,int r)
{
if(sz[o]-sz[last]<k)return;
if(l==r)
{c=l;return ;}
int mid=(l+r)>>1;
if(sz[ch[o][1]]-sz[ch[last][1]]>=k)cha(ch[o][1],ch[last][1],mid+1,r);
else k-=sz[ch[o][1]]-sz[ch[last][1]],cha(ch[o][0],ch[last][0],l,mid);
}
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int main()
{
//freopen("la.in","r",stdin);
scanf("%d%d%d",&n,&m,&q);for(i=1;i<=n*3;i++)fu[i]=i,v[i]=-1;
for(i=1;i<=n;i++)v[i]=read(),lin[i]=v[i];
for(i=1;i<=m;i++){
B[i].a=read();
B[i].b=read();
B[i].v=read();
}
tot=n;lin[n+1]=-1;
sort(lin+1,lin+2+n);
n++;
for(i=1;i<=n;i++)
ma[lin[i]]=i;
sort(B+1,B+1+m,cmp);
for(i=1;i<=m;i++)
{
int f1=zhao(B[i].a);
int f2=zhao(B[i].b);
if(f1==f2)continue;
++tot;
f[f1][0]=tot;
f[f2][0]=tot;
fu[f1]=tot;
fu[f2]=tot;
xia[tot].push_back(f1);
xia[tot].push_back(f2);
co[tot]=B[i].v;
}
dfs(tot);
dfs2(tot);
lrt[0]=last;
while(q--)
{
x=read();vv=read();k=read();
if(ans!=-1)x^=ans,vv^=ans,k^=ans;
for(i=20;i>=0;i--)
if(f[x][i]&&co[f[x][i]]<=vv)x=f[x][i];
c=1;
cha(lrt[x],qian[x],1,n);
if(c==1){
ans=-1;
printf("-1\n");
}else
{ans=lin[c];
printf("%d\n",ans);
}
}
}