洛谷4320:道路相遇——题解

https://www.luogu.com.cn/problem/P4320

BZOJ5329: [SDOI2018]战略游戏——题解的弱化版,但是我交上去RE了,猜测是复杂度不对,懒得再去算了于是把树链剖分拿了过来。

是的水了一篇博客

#include<cmath>
#include<queue>
#include<stack>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
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]]<size[v])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<l||l1>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/+

+++++++++++++++++++++++++++++++++++++++++++

posted @ 2020-02-06 20:28  luyouqi233  阅读(138)  评论(0编辑  收藏  举报