传送门:uoj30
题解
圆方树建出来:每个方点 x x x用multiset维护它的所有儿子圆点的 w i w_i wi, w x w_x wx就是multiset中的最小值。
每次修改至多影响两个点(该点和它的父结点),树剖维护即可。
代码
#include<bits/stdc++.h>
#define gc getchar
#define mid (l+r>>1)
#define lc k<<1
#define rc k<<1|1
using namespace std;
const int N=2e5+10;
typedef long long ll;
int n,m,q,num,tg[N],w[N],mn[N<<2];
int df[N],low[N],stk[N],top,dfn;
int sz[N],son[N],dep[N],tpo[N],f[N],rv[N],cnt;
ll ans;
multiset<int>st[N];
char cp;
template<class T>inline void rd(T &x)
{
cp=gc();x=0;int f=0;
for(;!isdigit(cp);cp=gc()) if(cp=='-') f=1;
for(;isdigit(cp);cp=gc()) x=x*10+(cp^48);
if(f) x=-x;
}
inline int ask_typ()
{
for(;;){
cp=gc();
if(cp=='C') return 0;
if(cp=='A') return 1;
}
}
struct gra{
int head[N],to[N<<1],nxt[N<<1],tot;
inline void lk(int u,int v)
{to[++tot]=v;nxt[tot]=head[u];head[u]=tot;}
}A,B;
void tar(int x)
{
int i,j,tp;df[x]=low[x]=++dfn;stk[++top]=x;
for(i=A.head[x];i;i=A.nxt[i]){
j=A.to[i];
if(!df[j]){
tar(j);
if(low[j]>=df[x]){
B.lk(x,++num);
for(;;){
tp=stk[top--];B.lk(num,tp);
st[num].insert(w[tp]);
if(tp==j) break;
}
}else low[x]=min(low[x],low[j]);
}else low[x]=min(low[x],df[j]);
}
}
void dfs1(int x)
{
int j,i;sz[x]=1;
if(x>n) w[x]=*(st[x].begin());
for(i=B.head[x];i;i=B.nxt[i]){
j=B.to[i];if(j==f[x]) continue;
f[j]=x;dep[j]=dep[x]+1;dfs1(j);sz[x]+=sz[j];
if((!son[x])||(sz[son[x]]<sz[j])) son[x]=j;
}
}
void dfs2(int x,int tpp)
{
int i,j;tpo[x]=tpp;tg[x]=++cnt;rv[cnt]=x;
if(!son[x]) return;dfs2(son[x],tpp);
for(i=B.head[x];i;i=B.nxt[i]){
j=B.to[i];if(j==f[x] || j==son[x]) continue;
dfs2(j,j);
}
}
inline void pu(int k){mn[k]=min(mn[lc],mn[rc]);}
void build(int k,int l,int r)
{
if(l==r) {mn[k]=w[rv[l]];return;}
build(lc,l,mid);build(rc,mid+1,r);
pu(k);
}
int qr(int k,int l,int r,int L,int R)
{
if(L<=l && r<=R) return mn[k];
if(R<=mid) return qr(lc,l,mid,L,R);
if(L>mid) return qr(rc,mid+1,r,L,R);
return min(qr(lc,l,mid,L,R),qr(rc,mid+1,r,L,R));
}
void trs(int k,int l,int r,int pos)
{
if(l==r) {mn[k]=w[rv[l]];return;}
if(pos<=mid) trs(lc,l,mid,pos);
else trs(rc,mid+1,r,pos);
pu(k);
}
inline int ask(int x,int y)
{
int re=2e9;
for(;tpo[x]!=tpo[y];x=f[tpo[x]]){
if(dep[tpo[x]]<dep[tpo[y]]) swap(x,y);
re=min(re,qr(1,1,num,tg[tpo[x]],tg[x]));
}
if(dep[x]<dep[y]) swap(x,y);
re=min(re,qr(1,1,num,tg[y],tg[x]));
if(y>n) re=min(re,w[f[y]]);
return re;
}
inline void chg(int x,int vl)
{
int y=f[x];
if(y){
st[y].erase(st[y].find(w[x]));
st[y].insert(vl);
w[y]=*(st[y].begin());
trs(1,1,num,tg[y]);
}
w[x]=vl;trs(1,1,num,tg[x]);
}
int main(){
int i,j,x,y;
rd(n);rd(m);rd(q);num=n;
for(i=1;i<=n;++i) rd(w[i]);
for(i=1;i<=m;++i){
rd(x);rd(y);
A.lk(x,y);A.lk(y,x);
}
tar(1);dep[1]=1;dfs1(1);dfs2(1,1);
build(1,1,num);
for(;q;--q){
if(ask_typ()){
rd(x);rd(y);printf("%d\n",ask(x,y));
}else{
rd(x);rd(y);chg(x,y);
}
}
return 0;
}