Divide and Conquer - Divide and Conquer tree line

The operation split into several different roles in the operation period, the time period divided by the segment tree division manner, so called partition tree line.

Take the following as examples Bzoj4025 it.

#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
const int N=1e5+5;
const int M=2e5+5;
const int TM=1e5+5;
const int S=2*TM;

struct edg{
    int u,v;
};
vector<edg>x[S];
int c[S][2],in[S][2];
int rt,cnt;

int sk[M],tp;

bool ans[TM];

int uf[N],sz[N],lz[N];

int bld(int l,int r){
    int v=++cnt,mid=(l+r)>>1;
    in[v][0]=l,
    in[v][1]=r;
    if(l==r)
        return v;
    c[v][0]=bld(l,mid),
    c[v][1]=bld(mid+1,r);
    return v;
}

void add(int v,edg e,int l,int r){
    if(l<=in[v][0]&&in[v][1]<=r){
        x[v].push_back(e);
        return;
    }
    if(l<=in[c[v][0]][1])
        add(c[v][0],e,l,r);
    if(in[c[v][1]][0]<=r)
        add(c[v][1],e,l,r);
}

int gtf(int v,int &l){
    if(uf[v]==v){
        l=lz[v];
        return v;
    }
    int f=gtf(uf[v],l);
    l^=lz[v];
    return f;
}

int mrg(edg e,int &s){
    int fu,fv,lu,lv;
    fu=gtf(e.u,lu),
    fv=gtf(e.v,lv);
    if(fu==fv)
        return lu^lv^1;
    if(sz[fu]<sz[fv])
        swap(fu,fv),
        swap(lu,lv);
    uf[fv]=fu;
    sz[fu]+=sz[fv];
    lz[fv]=lu^lv^1;
    sk[++tp]=fv;
    ++s;
    return 0;
}

void dlt(){
    int u=sk[tp],f,l;
    --tp;
    f=gtf(u,l);
    sz[f]-=sz[u];
    uf[u]=u;
    lz[u]=0;
}

void dfs(int v,int b){
    int i,t=b,s=0;
    for(i=0;i<x[v].size()&&t;i++)
        t^=mrg(x[v][i],s);
    if(in[v][0]==in[v][1])
        ans[in[v][0]]=t;
    else
        dfs(c[v][0],t),
        dfs(c[v][1],t);
    for(i=1;i<=s;i++)
        dlt();
}

int main()
{
    int n,m,t,i,u,v,b,e;
    scanf("%d%d%d",&n,&m,&t);
    rt=bld(1,t);
    for(i=1;i<=m;i++){
        scanf("%d%d%d%d",&u,&v,&b,&e);
        if(b<e)
            add(rt,(edg){u,v},b+1,e);
    }
    for(i=1;i<=n;i++)
        uf[i]=i,
        lz[i]=0,
        sz[i]=1;
    dfs(rt,1);
    for(i=1;i<=t;i++)
        printf(ans[i]?"Yes\n":"No\n");
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/l-ly-03/p/DivideAndConquer-SegmentTreeDC.html