あなたはこのqwqについて書くことをお勧めします:P2633
その後違いは、この質問は、(これは実際には大きな問題ではありません)にもエッジ動作だけでなく、森の整備を持っていることです。
それに近づくものを再訪...
私は今、クエリしたいと((U、V)\ \ ) 最初のパス\(K \)ように、小さな重み(\ T [U])\点を表す\(U \)ルートへのパス上の権利次に、重み値セグメントツリー形成され、\((U、V)\ ) 経路セグメントツリー上の重みである(T [U] + T \ [V] -T [LCA(U、V)] -T [LCAのfa_ {(U、V)}] \) 、セグメント重みは、バイナリツリーを下ることができます。
さて、でも操作側で...私はになっ?
ヒューリスティック精力的に十分合併、もし\(U \)一枚の大きさの比率\(V \) 、その後、一枚の大きさは大きなLET \(V \)(U \)\息子、または他のてみましょう\(V \)\(U \)の父。
これは非常に便利なメンテナンスすることができることを見出し\(U \)上記\(2 ^ I \)層の祖先乗算演算子\(LCA \)のみ。
また、...それはtestcase
...... ......これ以上測定データよりもデータセット数の数ではありません......
\(コード:\)
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;++i)
#define per(i,a,n) for (int i=n-1;i>=a;--i)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
typedef double db;
typedef long long ll;
typedef pair<int,int> PII;
typedef vector<int> VI;
const int N=3e5+10;
namespace Desc {
int val[N],tot;
inline void init(int *a,int n) {
rep(i,1,n+1) val[i]=a[i];
sort(val+1,val+n+1);
tot=unique(val+1,val+n+1)-val-1;
}
inline int getid(int x) {return lower_bound(val+1,val+tot+1,x)-val;}
inline int getval(int i) {return val[i];}
} // 离散化
using Desc::getid;
using Desc::getval;
int lc[N*40],rc[N*40],sum[N*40],oc=0,rt[N];
inline void clr(int &x) {lc[x]=rc[x]=sum[x]=0;}
inline int newnode() {int x=++oc;clr(x);return x;}
void build(int &x,int l,int r) {
x=newnode(); if(l==r) return; int mid=(l+r)>>1;
build(lc[x],l,mid),build(rc[x],mid+1,r);
}
void ins(int pre,int &x,int l,int r,int p,int v=1) {
x=newnode(); lc[x]=lc[pre],rc[x]=rc[pre],sum[x]=sum[pre]+v;
if(l==r) return; int mid=(l+r)>>1;
if(p<=mid) ins(lc[pre],lc[x],l,mid,p,v);
else ins(rc[pre],rc[x],mid+1,r,p,v);
}
int qry(int x,int y,int lca,int flca,int l,int r,int k) {
if(l==r) return l;
int mid=(l+r)>>1,sz=sum[lc[x]]+sum[lc[y]]-sum[lc[lca]]-sum[lc[flca]];
if(k<=sz) return qry(lc[x],lc[y],lc[lca],lc[flca],l,mid,k);
else return qry(rc[x],rc[y],rc[lca],rc[flca],mid+1,r,k-sz);
}
int n,m,a[N],Q,p[N][30],dep[N];
VI g[N];
#define LOGN 21
inline int getlca(int x,int y) {
if(dep[x]<dep[y]) swap(x,y);
per(i,0,LOGN) if(dep[p[x][i]]>=dep[y]) x=p[x][i];
if(x==y) return x;
per(i,0,LOGN) if(p[x][i]!=p[y][i]) x=p[x][i],y=p[y][i];
return p[x][0];
}
int F[N],siz[N],vis[N];
inline int find(int x) {return F[x]==x?F[x]:F[x]=find(F[x]);}
void dfs(int u,int ff,int deep,int pp) {
siz[pp]++,vis[u]=1,F[u]=pp;
int pos=getid(a[u]); ins(rt[ff],rt[u],1,Desc::tot,pos);
p[u][0]=ff; rep(i,1,LOGN) p[u][i]=p[p[u][i-1]][i-1]; // 倍增LCA
dep[u]=deep;
for (auto v:g[u]) if(v!=ff) dfs(v,u,deep+1,pp);
}
inline void merge(int u,int v) {
int pu=find(u),pv=find(v);
if(pu==pv) return;
if(siz[pu]<siz[pv]) swap(u,v),swap(pu,pv);
g[u].pb(v),g[v].pb(u);
dfs(v,u,dep[u]+1,pu);
}
inline int query(int u,int v,int k) {
int lca=getlca(u,v),flca=p[lca][0];
return getval(qry(rt[u],rt[v],rt[lca],rt[flca],1,Desc::tot,k));
}
inline int nc() {char ch;while(isspace(ch=getchar()));return ch;}
int main() {
#ifdef LOCAL
freopen("a.in","r",stdin);
#endif
scanf("%*d%d%d%d",&n,&m,&Q);
rep(i,1,n+1) scanf("%d",a+i);
Desc::init(a,n);
build(rt[0],1,Desc::tot);
rep(i,1,m+1) {
int u,v; scanf("%d%d",&u,&v);
g[u].pb(v),g[v].pb(u);
}
rep(i,1,n+1) F[i]=i;
rep(i,1,n+1) if(!vis[i]) dfs(i,0,1,i);
int lstans=0; while(Q--) {
char opt=nc();
int u,v,k;scanf("%d%d",&u,&v);
if(opt=='Q') {
scanf("%d",&k);
u^=lstans,v^=lstans,k^=lstans;
printf("%d\n",lstans=query(u,v,k));
} else {
u^=lstans,v^=lstans;
merge(u,v);
}
}
return 0;
}