[主席樹 Kruscal] BZOJ 3545 [ONTAK2010]Peaks & 3551 [ONTAK2010]Peaks加強版
阿新 • • 發佈:2019-02-06
Orz hzwer
#include<cstdio> #include<cstdlib> #include<algorithm> #define V G[p].v using namespace std; inline char nc() { static char buf[100000],*p1=buf,*p2=buf; if (p1==p2) { p2=(p1=buf)+fread(buf,1,100000,stdin); if (p1==p2) return EOF; } return *p1++; } inline void read(int &x) { char c=nc(),b=1; for (;!(c>='0' && c<='9');c=nc()) if (c=='-') b=-1; for (x=0;c>='0' && c<='9';x=x*10+c-'0',c=nc()); x*=b; } const int N=200005,K=21; int sx[N],icnt; inline int Bin(int x){ return lower_bound(sx+1,sx+icnt+1,x)-sx; } namespace SSeg{ const int M=5000005; int ncnt; int root[N]; int ls[M],rs[M],sum[M]; inline void Add(int &x,int y,int l,int r,int t) { if (!x) x=++ncnt; int mid=(l+r)>>1; if (l==r){ sum[x]=sum[y]+1; return; } if (t<=mid) Add(ls[x],ls[y],l,mid,t),rs[x]=rs[y]; else Add(rs[x],rs[y],mid+1,r,t),ls[x]=ls[y]; sum[x]=sum[ls[x]]+sum[rs[x]]; } inline int Query(int x,int y,int l,int r,int k) { if (l==r) { if (sum[y]-sum[x]>=k) return l; return -1; } int mid=(l+r)>>1,tem=sum[rs[y]]-sum[rs[x]]; if (k>tem) return Query(ls[x],ls[y],l,mid,k-tem); else return Query(rs[x],rs[y],mid+1,r,k); } } struct edge{ int u,v,next; }G[N<<1]; int head[N],inum; inline void add(int u,int v,int p) { G[p].u=u; G[p].v=v; G[p].next=head[u]; head[u]=p; } int wgt[N],val[N]; int tid[N],size[N],clk; int fat[N][K],maxv[N][K]; inline void dfs(int u,int fa){ using namespace SSeg; fat[u][0]=fa; maxv[u][0]=wgt[fa]; tid[u]=++clk; size[u]=1; for (int k=1;k<K;k++) fat[u][k]=fat[fat[u][k-1]][k-1],maxv[u][k]=max(maxv[u][k-1],maxv[fat[u][k-1]][k-1]); if (val[u]) Add(root[clk],root[clk-1],1,icnt,val[u]); else root[clk]=root[clk-1]; for (int p=head[u];p;p=G[p].next) dfs(V,u),size[u]+=size[V]; } inline int LCA(int u,int v){ for (int k=K-1;~k;k--) if (maxv[u][k]<=v) u=fat[u][k]; return u; } namespace TSet{ int fat[N],rank[N]; inline void init(int n){ for (int i=1;i<=n;i++) fat[i]=i; } inline int Fat(int u){ return fat[u]==u?u:fat[u]=Fat(fat[u]); } } int n,m; struct edges{ int u,v,w; bool operator < (const edges &B) const{ return w<B.w; } }D[500005]; int pcnt; inline void Krus(){ sort(D+1,D+m+1); TSet::init(n<<1); pcnt=n; int x,y,fx,fy; for (int i=1;i<=m;i++) { x=D[i].u; y=D[i].v; fx=TSet::Fat(x); fy=TSet::Fat(y); if (fx==fy) continue; ++pcnt; TSet::fat[fx]=pcnt; add(pcnt,fx,++inum); TSet::fat[fy]=pcnt; add(pcnt,fy,++inum); wgt[pcnt]=D[i].w; } wgt[0]=1<<30; dfs(pcnt,0); } int lastans; inline void Solve(){ using namespace SSeg; int u,v,k; read(u); read(v); read(k); u^=lastans; v^=lastans; k^=lastans; int lca=LCA(u,v); int ret=Query(root[tid[lca]-1],root[tid[lca]+size[lca]-1],1,icnt,k); if (ret==-1) printf("-1\n"),lastans=0; else printf("%d\n",lastans=sx[ret]); } int main() { int Q; read(n); read(m); read(Q); for (int i=1;i<=n;i++) read(val[i]),sx[++icnt]=val[i]; sort(sx+1,sx+icnt+1); icnt=unique(sx+1,sx+icnt+1)-sx-1; for (int i=1;i<=n;i++) val[i]=Bin(val[i]); for (int i=1;i<=m;i++) read(D[i].u),read(D[i].v),read(D[i].w); Krus(); while (Q--) Solve(); return 0; }