https://www.luogu.com.cn/problem/P4320
BZOJ5329: [SDOI2018]战略游戏——题解的弱化版,但是我交上去RE了,猜测是复杂度不对,懒得再去算了于是把树链剖分拿了过来。
是的水了一篇博客
#include#include #include #include #include #include #include using namespace std; typedef long long ll; const int N=2e6+5; const int M=2e6+5; inline int read(){ int X=0,w=0;char ch=0; while(!isdigit(ch)){w|=ch=='-';ch=getchar();} while(isdigit(ch))X=(X<<3)+(X<<1)+(ch^48),ch=getchar(); return w?-X:X; } struct node{ int u[M],v[M],nxt[M]; int cnt,head[N]; void init(){ cnt=0;memset(head,0,sizeof(head)); } void add(int U,int V){ u[++cnt]=U;v[cnt]=V;nxt[cnt]=head[U];head[U]=cnt; } }e,g; int n,m,T,w[N]; int dfn[N],low[N],to[N],t,l; stack<int>q; void tarjan(int u,int f){ dfn[u]=low[u]=++t; for(int i=g.head[u];i;i=g.nxt[i]){ int v=g.v[i]; if(!dfn[v]){ q.push(i);tarjan(v,u); low[u]=min(low[u],low[v]); if(low[v]>=dfn[u]){ int num;l++; do{ num=q.top();q.pop(); int x=g.u[num],y=g.v[num]; if(to[x]!=l){ to[x]=l; e.add(x,l+n);e.add(l+n,x); } if(to[y]!=l){ to[y]=l; e.add(y,l+n);e.add(l+n,y); } }while(num!=i); } }else if(low[u]>dfn[v]&&f!=v){ q.push(i);low[u]=dfn[v]; } } } bool is_square(int x){ return x>n; } int tot,fa[N],pos[N],idx[N],size[N],son[N],dep[N],top[N],val[N]; void dfs1(int u){ size[u]=1; for(int i=e.head[u];i;i=e.nxt[i]){ int v=e.v[i]; if(fa[u]==v)continue; fa[v]=u;dep[v]=dep[u]+1; dfs1(v);size[u]+=size[v]; if(!son[u]||size[son[u]] v; } } void dfs2(int u,int anc){ pos[u]=++tot;idx[tot]=u;top[u]=anc; if(!son[u])return; dfs2(son[u],anc); for(int i=e.head[u];i;i=e.nxt[i]){ int v=e.v[i]; if(v==fa[u]||v==son[u])continue; dfs2(v,v); } } inline void init(){ dep[1]=1; dfs1(1); dfs2(1,1); } int tr[N<<2]; void build(int a,int l,int r){ if(l==r){ tr[a]=(is_square(idx[l]))? 0:1; return; } int mid=(l+r)>>1; build(a<<1,l,mid);build(a<<1|1,mid+1,r); tr[a]=tr[a<<1]+tr[a<<1|1]; } inline int query(int a,int l,int r,int l1,int r1){ if(r1 r)return 0; if(l1<=l&&r<=r1)return tr[a]; int mid=(l+r)>>1; return query(a<<1,l,mid,l1,r1)+query(a<<1|1,mid+1,r,l1,r1); } inline int qry(int x,int y){ int ans=0; while(top[x]!=top[y]){ if(dep[top[x]]<dep[top[y]])swap(x,y); ans+=query(1,1,n+l,pos[top[x]],pos[x]); x=fa[top[x]]; } if(dep[x]>dep[y])swap(x,y); return ans+query(1,1,n+l,pos[x],pos[y]); } int main(){ n=read(),m=read(); for(int i=1;i<=m;i++){ int u=read(),v=read(); g.add(u,v);g.add(v,u); } tarjan(1,0); init();build(1,1,n+l); int T=read(); for(int i=1;i<=T;i++){ int x=read(),y=read(); printf("%d\n",qry(x,y)); } return 0; }
+++++++++++++++++++++++++++++++++++++++++++
+本文作者:luyouqi233。 +
+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+
+++++++++++++++++++++++++++++++++++++++++++