洛谷P4899/LOJ2865[IOI2018]狼人

首先如果是边权的话很明显是kruskal重构树了,那么类比,点权也可以用类似的方法搞,只不过把枚举边换成了枚举点

然后建两棵树跑树上倍增就可以得出一个点最多可以到达那些点,我们的目标是判断是否存在一个$u$使得$u$到$S$和$E$均联通。

那么考虑把两颗树的$dfs$序求出来,那么问题就变成了已知两个数列中的各一个区间,求区间是否有交的问题,以$dfn_a$为关键字进行排序,向主席树中插入$dfn_b$,最后用主席树查询即可。

洛谷代码(传统):

#include<cstdio>
#include<algorithm>
using namespace std;
const int N=200050;
const int M=800050;
char rB[1<<21],*rS,*rT;
inline char gc(){return rS==rT&&(rT=(rS=rB)+fread(rB,1,1<<21,stdin),rS==rT)?EOF:*rS++;}
inline int rd(){
    char c=gc();
    while(c<48||c>57)c=gc();
    int x=c&15;
    for(c=gc();c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c&15);
    return x;
}
int G[N],to[M],nxt[M],sz1=0,cnt[N<<5],lc[N<<5],rc[N<<5],rt[N],sz2=0,t[N],n;
struct kruskal{
    int _G[N],_to[N],_nxt[N],sz,f[18][N],dep[N],pa[N],dfn[N],maxn[N],dfsc;
    inline void init(){sz=dfsc=0;}
    inline void add(int u,int v){
        _to[++sz]=v;_nxt[sz]=_G[u];_G[u]=sz;
    }
    int gf(int x){return pa[x]==x?x:pa[x]=gf(pa[x]);}
    void dfs(int u,int fa){
        int i,v;
        dep[u]=dep[f[0][u]=fa]+1;
        dfn[u]=++dfsc;
        for(i=1;(1<<i)<dep[u];++i)f[i][u]=f[i-1][f[i-1][u]];
        for(i=_G[u];i;i=_nxt[i])if((v=_to[i])!=fa)dfs(v,u);
        maxn[u]=dfsc;
    }
    inline void build1(){
        int i,u,v,x,y,tot;
        for(i=0;i<n;++i)pa[i]=i;
        for(tot=u=n-1;u>=0;--u)
            for(i=G[u];i;i=nxt[i])if((v=to[i])>u&&(x=gf(u))!=(y=gf(v))){
                add(x,y);
                pa[y]=x;
                if(!--tot)return;
            }
    }
    inline void build2(){
        int i,u,v,x,y,tot;
        for(i=0;i<n;++i)pa[i]=i;
        for(tot=n-1,u=0;u<n;++u)
            for(i=G[u];i;i=nxt[i])if((v=to[i])<u&&(x=gf(u))!=(y=gf(v))){
                add(x,y);
                pa[y]=x;
                if(!--tot)return;
            }
    }
    inline int query1(int u,int L){
        for(short i=17;i>=0;--i)if((1<<i)<dep[u]&&f[i][u]>=L)u=f[i][u];
        return u;
    }
    inline int query2(int u,int R){
        for(short i=17;i>=0;--i)if((1<<i)<dep[u]&&f[i][u]<=R)u=f[i][u];
        return u;
    }
}a,b;
inline int cmp(int x,int y){return a.dfn[x]<a.dfn[y];}
inline void add(int u,int v){
    to[++sz1]=v;nxt[sz1]=G[u];G[u]=sz1;
    to[++sz1]=u;nxt[sz1]=G[v];G[v]=sz1;
}
int ins(int pre,int L,int R,int x){
    int o=++sz2;
    cnt[o]=cnt[pre]+1;
    if(L<R){
        int M=L+R>>1;
        if(x<=M){lc[o]=ins(lc[pre],L,M,x);rc[o]=rc[pre];}
        else{rc[o]=ins(rc[pre],M+1,R,x);lc[o]=lc[pre];}
    }
    return o;
}
bool query(int u,int v,int L,int R,int x,int y){
    if(x<=L&&y>=R)return cnt[v]-cnt[u];
    int M=L+R>>1;
    if(x<=M&&query(lc[u],lc[v],L,M,x,y))return 1;
    if(y>M&&query(rc[u],rc[v],M+1,R,x,y))return 1;
    return 0;
}
int main(){
    int m,q,i,u,v,x,y;
    n=rd();m=rd();q=rd();
    for(i=0;i<m;++i){
        u=rd();v=rd();
        add(u,v);
    }
    a.init();a.build1();a.dfs(0,-1);
    b.init();b.build2();b.dfs(n-1,-1);
    for(i=0;i<n;++i)t[i]=i;
    sort(t,t+n,cmp);
    for(i=1;i<=n;++i)rt[i]=ins(rt[i-1],1,n,b.dfn[t[i-1]]);
    while(q--){
        u=rd();v=rd();x=rd();y=rd();
        u=a.query1(u,x);v=b.query2(v,y);
        puts(query(rt[a.dfn[u]-1],rt[a.maxn[u]],1,n,b.dfn[v],b.maxn[v])?"1":"0");
    }
    return 0;
}
View Code

LOJ代码(交互):

#include<cstdio>
#include<algorithm>
#include<vector>
#include "werewolf.h"
using namespace std;
const int N=200050;
const int M=800050;
char rB[1<<21],*rS,*rT;
inline char gc(){return rS==rT&&(rT=(rS=rB)+fread(rB,1,1<<21,stdin),rS==rT)?EOF:*rS++;}
inline int rd(){
    char c=gc();
    while(c<48||c>57)c=gc();
    int x=c&15;
    for(c=gc();c>=48&&c<=57;c=gc())x=(x<<3)+(x<<1)+(c&15);
    return x;
}
int G[N],to[M],nxt[M],sz1=0,cnt[N<<5],lc[N<<5],rc[N<<5],rt[N],sz2=0,t[N],n;
struct kruskal{
    int _G[N],_to[N],_nxt[N],sz,f[18][N],dep[N],pa[N],dfn[N],maxn[N],dfsc;
    inline void init(){sz=dfsc=0;}
    inline void add(int u,int v){
        _to[++sz]=v;_nxt[sz]=_G[u];_G[u]=sz;
    }
    int gf(int x){return pa[x]==x?x:pa[x]=gf(pa[x]);}
    void dfs(int u,int fa){
        int i,v;
        dep[u]=dep[f[0][u]=fa]+1;
        dfn[u]=++dfsc;
        for(i=1;(1<<i)<dep[u];++i)f[i][u]=f[i-1][f[i-1][u]];
        for(i=_G[u];i;i=_nxt[i])if((v=_to[i])!=fa)dfs(v,u);
        maxn[u]=dfsc;
    }
    inline void build1(){
        int i,u,v,x,y,tot;
        for(i=0;i<n;++i)pa[i]=i;
        for(tot=u=n-1;u>=0;--u)
            for(i=G[u];i;i=nxt[i])if((v=to[i])>u&&(x=gf(u))!=(y=gf(v))){
                add(x,y);
                pa[y]=x;
                if(!--tot)return;
            }
    }
    inline void build2(){
        int i,u,v,x,y,tot;
        for(i=0;i<n;++i)pa[i]=i;
        for(tot=n-1,u=0;u<n;++u)
            for(i=G[u];i;i=nxt[i])if((v=to[i])<u&&(x=gf(u))!=(y=gf(v))){
                add(x,y);
                pa[y]=x;
                if(!--tot)return;
            }
    }
    inline int query1(int u,int L){
        for(short i=17;i>=0;--i)if((1<<i)<dep[u]&&f[i][u]>=L)u=f[i][u];
        return u;
    }
    inline int query2(int u,int R){
        for(short i=17;i>=0;--i)if((1<<i)<dep[u]&&f[i][u]<=R)u=f[i][u];
        return u;
    }
}a,b;
inline int cmp(int x,int y){return a.dfn[x]<a.dfn[y];}
inline void add(int u,int v){
    to[++sz1]=v;nxt[sz1]=G[u];G[u]=sz1;
    to[++sz1]=u;nxt[sz1]=G[v];G[v]=sz1;
}
int ins(int pre,int L,int R,int x){
    int o=++sz2;
    cnt[o]=cnt[pre]+1;
    if(L<R){
        int M=L+R>>1;
        if(x<=M){lc[o]=ins(lc[pre],L,M,x);rc[o]=rc[pre];}
        else{rc[o]=ins(rc[pre],M+1,R,x);lc[o]=lc[pre];}
    }
    return o;
}
bool query(int u,int v,int L,int R,int x,int y){
    if(x<=L&&y>=R)return cnt[v]-cnt[u];
    int M=L+R>>1;
    if(x<=M&&query(lc[u],lc[v],L,M,x,y))return 1;
    if(y>M&&query(rc[u],rc[v],M+1,R,x,y))return 1;
    return 0;
}
vector<int> check_validity(int N,vector<int> X,vector<int> Y,vector<int> S,vector<int> E,vector<int> L,vector<int> R){
    int m=X.size(),q=S.size(),i,u,v,x,y;
    vector<int> s;
    n=N;
    for(i=0;i<m;++i){
        u=X[i];v=Y[i];
        add(u,v);
    }
    a.init();a.build1();a.dfs(0,-1);
    b.init();b.build2();b.dfs(n-1,-1);
    for(i=0;i<n;++i)t[i]=i;
    sort(t,t+n,cmp);
    for(i=1;i<=n;++i)rt[i]=ins(rt[i-1],1,n,b.dfn[t[i-1]]);
    for(i=0;i<q;++i){
        u=S[i];v=E[i];x=L[i];y=R[i];
        u=a.query1(u,x);v=b.query2(v,y);
        s.push_back(query(rt[a.dfn[u]-1],rt[a.maxn[u]],1,n,b.dfn[v],b.maxn[v]));
    }
    return s;
}
View Code

猜你喜欢

转载自www.cnblogs.com/sunshine-chen/p/11281902.html