#include using namespace std; using Int = long long; //BEGIN CUT HERE struct HLDecomposition { int n,pos; vector > G; vector vid, head, sub, hvy, par, dep, inv, type; HLDecomposition(){} HLDecomposition(int sz): n(sz),pos(0),G(n), vid(n,-1),head(n),sub(n,1),hvy(n,-1), par(n),dep(n),inv(n),type(n){} void add_edge(int u, int v) { G[u].push_back(v); G[v].push_back(u); } void build(vector rs=vector(1,0)) { int c=0; for(int r:rs){ dfs(r); bfs(r, c++); } } void dfs(int rt) { using T = pair; stack st; par[rt]=-1; dep[rt]=0; st.emplace(rt,0); while(!st.empty()){ int v=st.top().first; int &i=st.top().second; if(i<(int)G[v].size()){ int u=G[v][i++]; if(u==par[v]) continue; par[u]=v; dep[u]=dep[v]+1; st.emplace(u,0); }else{ st.pop(); int res=0; for(int u:G[v]){ if(u==par[v]) continue; sub[v]+=sub[u]; if(res q({r}); while(!q.empty()){ int h=q.front();q.pop(); for(int i=h;i!=-1;i=hvy[i]) { type[i]=c; vid[i]=k++; inv[vid[i]]=i; head[i]=h; for(int j:G[i]) if(j!=par[i]&&j!=hvy[i]) q.push(j); } } } // for_each(vertex) // [l,r] <- attention!! void for_each(int u, int v, const function& f) { while(1){ if(vid[u]>vid[v]) swap(u,v); f(max(vid[head[v]],vid[u]),vid[v]); if(head[u]!=head[v]) v=par[head[v]]; else break; } } // for_each(edge) // [l,r] <- attention!! void for_each_edge(int u, int v, const function& f) { while(1){ if(vid[u]>vid[v]) swap(u,v); if(head[u]!=head[v]){ f(vid[head[v]],vid[v]); v=par[head[v]]; } else{ if(u!=v) f(vid[u]+1,vid[v]); break; } } } int lca(int u,int v){ while(1){ if(vid[u]>vid[v]) swap(u,v); if(head[u]==head[v]) return u; v=par[head[v]]; } } int distance(int u,int v){ return dep[u]+dep[v]-2*dep[lca(u,v)]; } }; //END CUT HERE /* signed main(){ int n; cin>>n; HLDecomposition lca(n); for(int i=0;i>k; for(int j=0;j>c; lca.add_edge(i,c); } } lca.build(); int q; cin>>q; while(q--){ int u,v; cin>>u>>v; cout< P; int n; vector > G,C,T; vector ord,low,belong; vector

B; BiconectedGraph(){} BiconectedGraph(int sz):n(sz),G(sz),C(sz),T(sz){} void add_edge(int u,int v){ G[u].push_back(v); G[v].push_back(u); } void input(int m,int offset){ int a,b; for(int i=0;iord[v]) swap(u,v); return ord[u]=0){ low[u]=min(low[u],ord[v]); }else{ dfs(v,u,k); low[u]=min(low[u],low[v]); } if(is_bridge(u,v)) B.push_back(P(u,v)); } } void fill_component(int c,int u){ C[c].push_back(u); belong[u]=c; for(int v:G[u]){ if(belong[v]>=0||is_bridge(u,v)) continue; fill_component(c,v); } } void add_component(int u,int &k){ if(belong[u]>=0) return; fill_component(k++,u); } int build(){ int k=0; ord.resize(n); low.resize(n); belong.resize(n); fill(ord.begin(),ord.end(),-1); fill(belong.begin(),belong.end(),-1); for(int u=0;u=0) continue; dfs(u,-1,k); } k=0; for(int i=0;i<(int)B.size();i++){ add_component(B[i].first,k); add_component(B[i].second,k); } for(int u=0;u struct SegmentTree{ typedef function F; typedef function G; int n; F f; G g; T d1; E d0; vector dat; SegmentTree(){}; SegmentTree(int n_,F f,G g,T d1, vector v=vector()): f(f),g(g),d1(d1){ init(n_); if(n_==(int)v.size()) build(n_,v); } void init(int n_){ n=1; while(n v){ for(int i=0;i=0;i--) dat[i]=f(dat[i*2+1],dat[i*2+2]); } void update(int k,E a){ k+=n-1; dat[k]=g(dat[k],a); while(k>0){ k=(k-1)/2; dat[k]=f(dat[k*2+1],dat[k*2+2]); } } inline T query(int a,int b){ T vl=d1,vr=d1; for(int l=a+n,r=b+n;l>=1,r>>=1) { if(l&1) vl=f(vl,dat[(l++)-1]); if(r&1) vr=f(dat[(--r)-1],vr); } return f(vl,vr); } }; signed main(){ int n,e,q; scanf("%d %d %d",&n,&e,&q); BiconectedGraph big(n); big.input(e,-1); int E=0,V=big.build(); HLDecomposition hl(V); for(int i=0;i rmq(V, [](int a,int b){return max(a,b);}, [](int a,int b){return b;}, -1); vector > pq(V); map m; int num=0; for(int i=0;i