题目大意:见https://www.cnblogs.com/Mrsrz/p/9354136.html
强制在线
解题思路:
Kruskal重构树。
我们从小到大加入边,每次合并两个连通块时,新建一个节点作为它们的父亲,点权为原来的边权。
然后对于每个询问,倍增找最上方的点权不超过x的点,则该点构成的子树上的所有叶子节点就是原来的点能到的所有节点。
于是对每棵子树建主席树,查询时就是在子树内查询第k大。建主席树时相当于线段树合并。
C++ Code:
#include<bits/stdc++.h>
#define N 100005
template<typename T>
inline void read(T&d){
d=0;static int c;
for(c=getchar();!isdigit(c);c=getchar());
for(;isdigit(c);c=getchar())
d=(d<<3)+(d<<1)+(c^'0');
}
struct edge{
int u,v,dis;
inline bool operator<(const edge&rhs)const{return dis<rhs.dis;}
}E[N*5];
struct Edge{
int to,nxt;
}e[N<<3];
struct segmentTreeNode{
int s,ls,rs;
}d[6000005];
int n,m,q,h[N],fa[N<<1],nodes,f[N<<1][19],cnt=0,dang[N<<1],head[N<<1],hh[N],rt[N<<1];
int treenode=0;
inline int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
void init(int l,int r,int&o,int p){
o=++treenode;
d[o].s=1;
if(l==r)return;
int mid=l+r>>1;
if(p<=mid)init(l,mid,d[o].ls,p);else
init(mid+1,r,d[o].rs,p);
}
int merge(int ls,int rs){
if(!ls||!rs)return ls|rs;
int nw=++treenode;
if(!d[ls].ls&&!d[ls].rs){
d[nw].s=d[ls].s+d[rs].s;
return nw;
}
d[nw].ls=merge(d[ls].ls,d[rs].ls);
d[nw].rs=merge(d[ls].rs,d[rs].rs);
d[nw].s=d[d[nw].ls].s+d[d[nw].rs].s;
return nw;
}
void dfs(int now){
for(int i=head[now];i;i=e[i].nxt){
dfs(e[i].to);
if(!rt[now])rt[now]=rt[e[i].to];else
rt[now]=merge(rt[now],rt[e[i].to]);
}
if(!head[now])
init(0,N,rt[now],hh[now]);
}
int query(int l,int r,int&o,int k){
if(l==r)return l;
int mid=l+r>>1;
if(d[d[o].rs].s>=k)return query(mid+1,r,d[o].rs,k);
return query(l,mid,d[o].ls,k-d[d[o].rs].s);
}
int main(){
read(n),read(m),read(q);
for(int i=1;i<=n;++i)read(h[i]),hh[i]=h[i];
std::sort(h+1,h+n+1);
int nn=std::unique(h+1,h+n+1)-h-1;
for(int i=1;i<=n;++i)hh[i]=std::lower_bound(h+1,h+nn+1,hh[i])-h;
for(int i=1;i<=m;++i)read(E[i].u),read(E[i].v),read(E[i].dis);
std::sort(E+1,E+m+1);
for(int i=1;i<=n;++i)fa[i]=i,fa[i+n]=i+n;
nodes=n;
for(int less_node=n-1,i=1;less_node&&i<=m;++i){
int x=find(E[i].u),y=find(E[i].v);
if(x!=y){
fa[x]=fa[y]=f[x][0]=f[y][0]=++nodes;
dang[nodes]=E[i].dis;
--less_node;
e[++cnt]=(Edge){x,head[nodes]};
head[nodes]=cnt;
e[++cnt]=(Edge){y,head[nodes]};
head[nodes]=cnt;
}
}
dang[0]=0x3f3f3f3f;
memset(d,0,sizeof d);
dfs(nodes);
for(int j=1;j<19;++j)
for(int i=1;i<=nodes;++i)
f[i][j]=f[f[i][j-1]][j-1];
int ans=0;
while(q--){
int u,x,k;
read(u),read(x),read(k);
u^=ans,x^=ans,k^=ans;
for(int i=18;~i;--i)if(dang[f[u][i]]<=x)u=f[u][i];
if(d[rt[u]].s<k)puts("-1"),ans=0;else
printf("%d\n",ans=h[query(0,N,rt[u],k)]);
}
return 0;
}