带修维护两点间简单路径能经过的最小点权,n,q<=1e5
可以用圆方树重构图为树:对每个点双联通分量新建一个点表示,到对应点连边,割边保留,删去其余边,每个新建的点维护所有孩子的最小值,外加树链剖分查询链最值,特判lca的父亲。
#include<bits/stdc++.h> const int N=100007,inf=0x7fffffff; char ib[N*100],*ip=ib,ob[N*20],*op=ob; int _(){ int x=0; while(*ip<48)++ip; while(*ip>47)x=x*10+*ip++-48; return x; } void pr(int x){ int ss[15],sp=0; do ss[++sp]=x%10;while(x/=10); while(sp)*op++=ss[sp--]+48; *op++=10; } int n,m,q,v0[N],_n; int fa[N*2],sz[N*2],son[N*2],dep[N*2],top[N*2],id[N*2],idp=0; std::vector<int>e[N*2],E[N]; int mx,tr[555555]; void f1(int w,int pa){ dep[w]=dep[fa[w]=pa]+(sz[w]=1); for(int i=0;i<e[w].size();++i){ int u=e[w][i]; f1(u,w); sz[w]+=sz[u]; if(sz[u]>sz[son[w]])son[w]=u; } } void f2(int w,int tp){ top[w]=tp; id[w]=++idp; if(son[w])f2(son[w],tp); for(int i=0;i<e[w].size();++i){ int u=e[w][i]; if(u!=son[w])f2(u,u); } } struct dheap{ std::priority_queue<int,std::vector<int>,std::greater<int> >q,qd; void ins(int x){q.push(x);} void del(int x){qd.push(x);} int top(){ if(q.size()==qd.size())return inf; while(qd.size()&&q.top()==qd.top())q.pop(),qd.pop(); return q.top(); } void pop(){ while(qd.size()&&q.top()==qd.top())q.pop(),qd.pop(); q.pop(); } }ds[N*2]; void mins(int&a,int b){if(a>b)a=b;} int min(int a,int b){return a<b?a:b;} int qmn(int L,int R){ int v=inf; for(L+=mx-1,R+=mx+1;R-L!=1;L>>=1,R>>=1){ if(~L&1)mins(v,tr[L+1]); if(R&1)mins(v,tr[R-1]); } return v; } void set(int x,int y){ tr[x+=mx]=y; for(x>>=1;x;x>>=1){ int z=min(tr[x<<1],tr[(x<<1)+1]); if(z!=tr[x])tr[x]=z; else break; } } void que(int x,int y){ int a=top[x],b=top[y],v=inf; while(a!=b){ if(dep[a]<dep[b])std::swap(x,y),std::swap(a,b); mins(v,qmn(id[a],id[x])); x=fa[a],a=top[x]; } if(dep[x]<dep[y])std::swap(x,y); mins(v,qmn(id[y],id[x])); if(y>n&&fa[y])mins(v,v0[fa[y]]); pr(v); } void modify(int x,int y){ int f=fa[x]; if(f>n){ ds[f].del(v0[x]); ds[f].ins(y); set(id[f],ds[f].top()); } v0[x]=y; set(id[x],y); } int dfn[N],low[N],tk,ss[N],sp=0; void tj(int w,int pa){ dfn[w]=low[w]=++tk; ss[++sp]=w; for(int i=0;i<E[w].size();++i){ int u=E[w][i]; if(u==pa)continue; if(!dfn[u]){ tj(u,w); mins(low[w],low[u]); if(dfn[w]<low[u])e[w].push_back(ss[sp--]); else if(dfn[w]<=low[u]){ v0[++_n]=inf; while(1){ int x=ss[sp--]; ds[_n].ins(v0[x]); e[_n].push_back(x); if(x==u)break; } e[w].push_back(_n); } }else mins(low[w],dfn[u]); } } int main(){ fread(ib,1,sizeof(ib),stdin); n=_();m=_();q=_(); for(int i=1;i<=n;++i)v0[i]=_(); for(int i=0,a,b;i<m;++i){ a=_();b=_(); E[a].push_back(b); E[b].push_back(a); } _n=n; tj(1,0); f1(1,0);f2(1,1); for(mx=1;mx<=_n+5;mx<<=1); for(int i=1;i<=n;++i)tr[mx+id[i]]=v0[i]; for(int i=n+1;i<=_n;++i)tr[mx+id[i]]=ds[i].top(); for(int i=mx-1;i;--i)tr[i]=min(tr[i<<1],tr[(i<<1)+1]); for(int i=0,o,a,b;i<q;++i){ o=_();a=_();b=_(); if(o=='A'-48)que(a,b); else modify(a,b); } fwrite(ob,1,op-ob,stdout); return 0; }