On the segment tree Divide and Conquer

线段树分治

First we have to understand what the tree line (now refers to the narrow tree line) Yes.

Segment tree is a data structure easier to maintain the interval, an interval of the partition entity product.

Accurate, such as your maintenance interval [L, R],

In fact, we can continue to divide and conquer the midpoint down.

Since the partition interval length every time divided by two, so that up to log partition layer, to form a segment tree.

Then the segment tree partition refers to what?

Is actually a maintenance time interval data structure, the same partition of the tree line use, so that the complexity of the guarantee in the log level.

However, things have a lot of maintenance time interval,

Such as CDQ partition , KD-Tree , this type of data structure can maintain time interval ,

That segment tree partition of the special role where is it?

In fact, in general, its role is to support the revocation of operation, or maintenance is a time interval affected by the operation.

example:

Title effect
has a picture, n-points, m edges, while the right side there.

There are three modes of operation: edging, edge deletion, the query graph into two set points after two endpoints belong to the same side of the minimum value of a maximum set point.

solution:

After each side ordering the inquiry that currently exist, adding descending order, after adding an edge if the odd ring , then this edge is the answer

Can be found, those added to the list only produce even edge ring is of no use .

Therefore, only O (n) edges to be useful (i.e. no ring side edges and the first ring, odd).

Consider segment tree partition , the time interval where its each edge is added to the segment tree.

Each node of the tree line, there will be many sides.

Useful preprocessing on each node of the O (n) edges.

Always ask then is the information on the O (logn) nodes merger.

So ask for the number of times Q.

Since it can ask segment tree seen as a time to build, then the tree line, only O (Q) node.

Information about each node can come by his father

#include<bits/stdc++.h>
using namespace std;
const int MAX_N=5+1e3;
int n;
struct DSF{
    int fa[MAX_N],p[MAX_N];
    void make_set(int x){ fa[x]=x,p[x]=0; }
    int find_set(int x){ //并查集维护奇偶性
        if(fa[x]!=x){
            int y=fa[x];
            fa[x]=find_set(fa[x]);
            p[x]^=p[y];
        }
        return fa[x];
    }
    bool merge(int x,int y){
        if(find_set(x)==find_set(y))
            return p[x]^p[y];
        int u=find_set(x),v=find_set(y);
        p[u]=p[x]^p[y]^1;
        fa[u]=v;
        return true;
    }
    bool member(int x,int y){
        return find_set(x)==find_set(y);
    }
}dsf;
struct E{ int x,y,k; };
struct Q{ E x; int l,r; };
inline bool operator<(E a,E b){ return a.k>b.k; }
vector<Q> e;
struct SEG{
    vector<E> tree[MAX_N<<2];
    void build(int p,int l,int r){
        tree[p].clear(); 
        if(l==r) return;
        int mid=l+r>>1;
        build(p+p,l,mid);
        build(p+p+1,mid+1,r);
    }
    void change(int p,int l,int r,int x,int y,E key){
        if(l==x&&r==y){
            tree[p].push_back(key);
            return;
        }
        int mid=l+r>>1;
        if(y<=mid) return change(p+p,l,mid,x,y,key);
        else if(x>mid) return change(p+p+1,mid+1,r,x,y,key);
        else change(p+p,l,mid,x,mid,key),change(p+p+1,mid+1,r,mid+1,y,key);
    }
    void dfs(int p,int l,int r,vector<E> k,int ans){    
        for(int i=0;i<tree[p].size();++i)
            k.push_back(tree[p][i]);
        sort(k.begin(),k.end());
        for(int i=1;i<=n;++i) dsf.make_set(i);
        for(int i=0;i<k.size();++i){ 
            if(!dsf.member(k[i].x,k[i].y)){
                dsf.merge(k[i].x,k[i].y);
            }else{
                if(!dsf.merge(k[i].x,k[i].y)){
                    ans=max(ans,k[i].k);
                    k.resize(i);//只保留[0,i-1] 
                     break;
                }
            }
        }
        if(l==r){
            printf("%d\n",ans);
            return;
        }
        int mid=l+r>>1;
        dfs(p+p,l,mid,k,ans);
        dfs(p+p+1,mid+1,r,k,ans);
    }
}seg;
int main(){
    int m,q; scanf("%d%d%d",&n,&m,&q);
    e.resize(m+1); 
    for(int i=1;i<=m;++i){ 
        scanf("%d%d%d",&e[i].x.x,&e[i].x.y,&e[i].x.k);
        e[i].l=1; e[i].r=-1;
    }
    vector<E> k; for(int i=1;i<=m;++i) k.push_back(e[i].x);
    sort(k.begin(),k.end());
    for(int i=1;i<=n;++i) dsf.make_set(i);
    int top=1;
    for(int i=1;i<=q;++i){
        char c=getchar();
        while(c<'A'||c>'Z') c=getchar();
        if(c=='D'){
            int x; scanf("%d",&x);
            e[x].r=top-1;
        }else if(c=='A'){
            e.push_back((Q){{0,0,0},0,0}); ++m;
            scanf("%d%d%d",&e[m].x.x,&e[m].x.y,&e[m].x.k);
            e[m].l=top; e[m].r=-1;
        }else{
            ++top;
        }
    }
    for(int i=1;i<=m;++i)
        if(e[i].r==-1) e[i].r=top-1;
    --top;
    seg.build(1,1,top);
    for(int i=1;i<=m;++i)
        if(e[i].l<=e[i].r)
            seg.change(1,1,top,e[i].l,e[i].r,e[i].x);
    seg.dfs(1,1,top,vector<E>(),0);
    return 0;
}

Guess you like

Origin www.cnblogs.com/wzxbeliever/p/11604715.html