kruskal重构树。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define maxv 200050 #define maxe 2000050 #define inf 2147483647 using namespace std; struct edges { int u,v,w; }es[maxe]; struct edge { int v,nxt; }e[maxe]; int n,m,q,h[maxv],hash[maxv],x,y,z,lastans=0,val[maxv],g[maxv],nume=0,father[maxv]; int dis[maxv],l[maxv],r[maxv],fdfn[maxv],anc[maxv][21],times=0; int root[maxv],tot=0,tots=0,ls[maxv*23],rs[maxv*23],sum[maxv*23],len; bool cmp(edges x,edges y) { return x.w<y.w; } int read() { char ch;int data=0; while (ch<'0' || ch>'9') ch=getchar(); while (ch>='0' && ch<='9') { data=data*10+ch-'0'; ch=getchar(); } return data; } void addedge(int u,int v) { e[++nume].v=v; e[nume].nxt=g[u]; g[u]=nume; } int getfather(int x) { if (father[x]!=x) father[x]=getfather(father[x]); return father[x]; } void kruskal_tree() { sort(es+1,es+m+1,cmp); for (int i=1;i<=2*n;i++) father[i]=i; for (int i=1;i<=m;i++) { int u=es[i].u,v=es[i].v,w=es[i].w; int f1=getfather(es[i].u),f2=getfather(es[i].v); if (f1!=f2) { tot++; father[f1]=tot;father[f2]=tot;val[tot]=es[i].w; addedge(f1,tot);addedge(tot,f1);addedge(f2,tot);addedge(tot,f2); } } } void dfs(int x) { int flag=0;l[x]=inf;r[x]=0; for (int i=g[x];i;i=e[i].nxt) { int v=e[i].v; if (anc[x][0]!=v) { flag=1; anc[v][0]=x;dis[v]=dis[x]+1; dfs(v); l[x]=min(l[x],l[v]);r[x]=max(r[x],r[v]); } } if (!flag) { l[x]=r[x]=++times; fdfn[times]=x; } } void get_table() { for (int e=1;e<=20;e++) for (int i=1;i<=tot;i++) anc[i][e]=anc[anc[i][e-1]][e-1]; } int bnd(int x) { return lower_bound(hash+1,hash+len+1,x)-hash; } void insert(int last,int &now,int left,int right,int pos) { now=++tots;sum[now]=sum[last]+1; if (left==right) return; ls[now]=ls[last];rs[now]=rs[last]; int mid=left+right>>1; if (pos<=mid) insert(ls[last],ls[now],left,mid,pos); else insert(rs[last],rs[now],mid+1,right,pos); } void build_seg() { sort(hash+1,hash+n+1); len=unique(hash+1,hash+n+1)-hash-1; for (int i=1;i<=n;i++) insert(root[i-1],root[i],1,len,bnd(h[fdfn[i]])); } int find(int x,int k) { for (int e=20;e>=0;e--) { if ((val[anc[x][e]]<=k) && (anc[x][e])) x=anc[x][e]; } return x; } int ask(int last,int now,int left,int right,int k) { if (left==right) return hash[left]; int mid=left+right>>1; int r=sum[rs[now]]-sum[rs[last]]; if (r>=k) return ask(rs[last],rs[now],mid+1,right,k); else return ask(ls[last],ls[now],left,mid,k-r); } void work() { x=read();y=read();z=read(); x^=lastans;y^=lastans;z^=lastans; int k=find(x,y); if (r[k]-l[k]+1<z) {printf("-1\n");lastans=0;} else { lastans=ask(root[l[k]-1],root[r[k]],1,len,z); printf("%d\n",lastans); } } int main() { n=read();m=read();q=read();tot=n; for (int i=1;i<=n;i++) {h[i]=read();hash[i]=h[i];} for (int i=1;i<=m;i++) {es[i].u=read();es[i].v=read();es[i].w=read();} kruskal_tree(); dfs(tot); get_table(); build_seg(); for (int i=1;i<=q;i++) work(); return 0; }