Description
【题目描述】同3545
Input
第一行三个数N,M,Q。
第二行N个数,第i个数为h_i
接下来M行,每行3个数a b c,表示从a到b有一条困难值为c的双向路径。
接下来Q行,每行三个数v x k,表示一组询问。v=v xor lastans,x=x xor lastans,k=k xor lastans。如果lastans=-1则不变。
Output
同3545
Sample Input
Sample Output
HINT
【数据范围】同3545
Source
不强制在线肯定会,平衡树启发式合并一下就行了
至于强制在线..
黄学长的题解
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define MAXN 100010
#define SIZE 5000010
#define LL long long
#define GET (ch>='0'&&ch<='9')
using namespace std;
inline void in(int &x)
{
char ch=getchar();x=0;int flag=1;
while (!GET) flag=ch=='-'?-1:1,ch=getchar();
while (GET) x=x*10+ch-'0',ch=getchar();x*=flag;
}
int n,m,q,cnt,top,lastans;
int Pow[20],h[MAXN],que[MAXN];
int f[MAXN<<1];
int sta[MAXN<<2],tp,In[MAXN<<1],Out[MAXN<<1];
int deep[MAXN<<1],val[MAXN<<1],fa[MAXN<<1][20],maxn[MAXN<<1][20];
int root[MAXN<<2],ls[SIZE],rs[SIZE],sz[SIZE];
bool vis[MAXN<<1];
inline int find(int x) { return f[x]==x?x:f[x]=find(f[x]); }
struct edge { int to; edge *next; }e[MAXN<<1],*prev[MAXN<<1];
inline void insert(int u,int v) { e[++top].to=v;e[top].next=prev[u];prev[u]=&e[top]; }
struct Edge
{
int u,v,w;
inline bool operator <(const Edge& a)const { return w<a.w; }
}s[MAXN*5];
void ins(int x,int &y,int l,int r,int val)
{
sz[y=++cnt]=sz[x]+1;
ls[y]=ls[x];rs[y]=rs[x];
if (l==r) return;
int mid=(l+r)>>1;
if (val<=mid) ins(ls[x],ls[y],l,mid,val);
else ins(rs[x],rs[y],mid+1,r,val);
}
int query(int x,int y,int l,int r,int k)
{
if (l==r) return l;
int mid=(l+r)>>1;
if (sz[ls[y]]-sz[ls[x]]>=k) return query(ls[x],ls[y],l,mid,k);
else return query(rs[x],rs[y],mid+1,r,k-sz[ls[y]]+sz[ls[x]]);
}
void dfs(int x)
{
vis[x]=1;sta[++tp]=x;
for (int i=1;i<=16;i++)
if (deep[x]>=Pow[i]) fa[x][i]=fa[fa[x][i-1]][i-1],maxn[x][i]=max(maxn[x][i-1],maxn[fa[x][i-1]][i-1]);
else break;
for (edge *i=prev[x];i;i=i->next)
deep[i->to]=deep[x]+1,maxn[i->to][0]=val[x],fa[i->to][0]=x,dfs(i->to);
if (x>n) sta[++tp]=x;
}
inline int get_f(int x,int val)
{
for (int i=17;i>=0;i--) if (deep[x]>=Pow[i]&&maxn[x][i]<=val) x=fa[x][i];
return x;
}
int main()
{
for (int i=0;i<20;i++) Pow[i]=(1<<i);
in(n);in(m);in(q);
int tot=n,v,x,k,t;
for (int i=1;i<=n;i++) in(h[i]),que[i]=h[i];
sort(que+1,que+n+1);//t=unique(que+1,que+n+1)-que;
for (int i=1;i<=n;i++) h[i]=lower_bound(que+1,que+n+1,h[i])-que;
for (int i=1;i<=(n<<1);i++) f[i]=i;
for (int i=1;i<=m;i++) in(s[i].u),in(s[i].v),in(s[i].w);
sort(s+1,s+m+1);
for (int i=1;i<=m;i++)
{
int x=find(s[i].u),y=find(s[i].v);
if (x!=y)
{
tot++;f[x]=f[y]=tot;val[tot]=s[i].w;
insert(tot,x);insert(tot,y);
if (tot==(n<<1)-1) break;
}
}
for (int i=1;i<=n;i++) if (!vis[i]) dfs(find(i));
for (int i=1;i<=tp;i++)
{
int t=sta[i];
if (t<=n) ins(root[i-1],root[i],1,n,h[t]);
else
{
root[i]=root[i-1];
if (!In[t]) In[t]=i; else Out[t]=i;
}
}
while (q--)
{
in(v);in(x);in(k);
if (lastans!=-1) v^=lastans,x^=lastans,k^=lastans;
int t=get_f(v,x),a=root[In[t]],b=root[Out[t]];
if (sz[b]-sz[a]<k) lastans=-1;
else lastans=que[query(a,b,1,n,sz[b]-sz[a]-k+1)];
printf("%d\n",lastans);
}
}