More than 2019 cattle off summer school camp (Session 8) E + segment tree revocable disjoint-set

Topic Portal

Meaning of the questions:

  And m is given undirected edges, each edge has a $ [l, r] $, meaning that the volume of people within this range by this edge, the possibility to ask how many volumes have to make one from 1 to n

Idea: As is undirected edges, 1 and n connectivity can be maintained with disjoint-set.

  Consider the most violent approach, each enumerator volume, the volume can be maintained at the current edge with disjoint-set, it is determined to 1 to n connectivity.

  Consider optimization, first of all sections must be discrete, and we can be discrete intervals in accordance with the tree line dividing what way, then even look at each sub-section side with the disjoint-set, determine the connectivity, then leave this child when the interval, even the disjoint-set edge operating return on it.

  Since each edge is divided up into a log intervals, i.e. are added disjoint-set time log, log open times, the time complexity is (n * logn * logn), wherein a log is brought disjoint-set , the constant is small.

  Revocable by rank with disjoint-set to complete the merger, and the back operation only a continuous period of time, there are 2 * n th point discretization, segment tree points Do not open too.

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define dep(i,b,a) for(int i=b;i>=a;i--)
#define pb(x) push_back(x)
#define pii pair<int,int >
using namespace std;
const int maxn=200010;
vector<int >tr[maxn<<2];
int n,m;
struct edge{
    int u,v,l,r;
}a[maxn];
int b[maxn<<1],cnt,ans;
int fa[maxn],siz[maxn];
int find(int x){
    return x==fa[x]?x:find(fa[x]);
}
void update(int o,int l,int r,int ql,int qr,int i){
    if(ql<=l&&r<=qr){
        tr[o].pb(i);
        return;
    }
    int mid=(l+r)>>1;
    if(ql<=mid)update(o<<1,l,mid,ql,qr,i);
    if(mid<qr)update(o<<1|1,mid+1,r,ql,qr,i);
}
void dfs(int o,int l,int r){
    vector<pii >ve;
    int si=tr[o].size();
    rep(i,0,si-1){
        int id=tr[o][i];
        int u=a[id].u,v=a[id].v;
        int fu=find(u),fv=find(v);
        if(fu==fv)continue;
        if(siz[fu]>siz[fv])swap(fu,fv);
        fa[fu]=fv;
        int d=0;
        if(siz[fu]==siz[fv])d++;
        siz[fv]+=d;
        ve.push_back({fu,d});
    }
    int mid=(l+r)>>1;
    if(find(1)==find(n)){
        ans+=b[r+1]-b[l];
    }else if(l<r){
        dfs(o<<1,l,mid);
        dfs(o<<1|1,mid+1,r);
    }
    si=ve.size();
    dep(i,si-1,0){
        siz[fa[ve[i].first]]-=ve[i].second;
        fa[ve[i].first]=ve[i].first;
    }
}
int main(){
    cin>>n>>m;
    rep(i,1,n){
        fa[i]=i;
        siz[i]=1;
    }
    for(int i=1;i<=m;i++){
        scanf("%d%d%d%d",&a[i].u,&a[i].v,&a[i].l,&a[i].r);
        b[++cnt]=a[i].l;
        b[++cnt]=a[i].r+1;
    }
    sort(b+1,b+1+cnt);
    cnt=unique(b+1,b+1+cnt)-b-1;
    for(int i=1;i<=m;i++){
        a[i].l=lower_bound(b+1,b+1+cnt,a[i].l)-b;
        a[i].r=lower_bound(b+1,b+1+cnt,a[i].r+1)-b;
        update(1,1,cnt,a[i].l,a[i].r-1,i);
    }
    dfs(1,1,cnt);
    printf("%d\n",ans);
}

 

Guess you like

Origin www.cnblogs.com/mountaink/p/11334120.html