hiho1996: 01 matching segment tree

hiho1996: 01 matching segment tree

https://hihocoder.com/problemset/problem/1996

The meaning of problems

Do you have a map n points.

The right to the i-th point values ​​ai, a weight of each point may only be 1 or 0.

There between the point i and the point j even edges, if and only if the following two conditions are met:

i < j

ai = 1, and aj = 0

There are times q ask, ask each given l and r, please answer: If we retain only the label point between [l, r], retaining only in [l, r] those numbered between two endpoints side, then the maximum matching this figure is the amount of output please the maximum number of matches.

Thinking

Strange title description of iffy, a closer look at what this requirement is associative, that is the answer plus maintenance intervals and the number 0 1 extra, you can merge two adjacent intervals. Clearly put forward a segment tree can do.
ps. Now do the tree line, in fact, that this thing is the interval changes.

Code

#include<bits/stdc++.h>
using namespace std;
#define X first
#define Y second
#define PB push_back
#define MP make_pair
#define MEM(a,b) memset(a,b,sizeof(a))
typedef long long ll;
const ll mod = 1e9+7;
const int maxn =3e6+10;

int sum[maxn][2],sit[maxn];

inline int lson(int x){return x*2;}

inline int rson(int x){return x*2+1;}

void push_up(int rt){
    sit[rt]=sit[lson(rt)]+sit[rson(rt)];
    sum[rt][0]=sum[lson(rt)][0]+sum[rson(rt)][0];
    sum[rt][1]=sum[lson(rt)][1]+sum[rson(rt)][1];
    if(sum[lson(rt)][1]>0&&sum[rson(rt)][0]>0){
        sit[rt]+=min(sum[lson(rt)][1],sum[rson(rt)][0]);
        sum[rt][1]-=min(sum[lson(rt)][1],sum[rson(rt)][0]);
        sum[rt][0]-=min(sum[lson(rt)][1],sum[rson(rt)][0]);
    }
}

void build(int rt,int L,int R,vector<int> &a){
    if(L==R){
        sit[rt]=0;
        sum[rt][a[L]]++;
        return;
    }
    int mid=(L+R)/2;
    build(lson(rt),L,mid,a);
    build(rson(rt),mid+1,R,a);
    push_up(rt);
}

pair<int,pair<int,int>> query(int rt,const int l,const int r,int L,int R){
    if(L>=l&&R<=r) return {sit[rt],{sum[rt][0],sum[rt][1]}};
    if(l>R||r<L) return {0,{0,0}};
    int mid=(L+R)/2;
    auto ll=query(lson(rt),l,r,L,mid);
    auto rr=query(rson(rt),l,r,mid+1,R);
    if(ll.X==-1) return rr;
    else if(rr.X==-1) return ll;
    else{
        pair<int,pair<int,int>> ret;
        ret.X=ll.X+rr.X;
        ret.Y.X=ll.Y.X+rr.Y.X;
        ret.Y.Y=ll.Y.Y+rr.Y.Y;
        int mi=min(ll.Y.Y,rr.Y.X);
        ret.Y.X-=mi;
        ret.Y.Y-=mi;
        ret.X+=mi;
        return ret;
    }
}

int main(){
    int n,m,l,r;
    cin>>n;
    vector<int> a(n+1,0);
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,1,n,a);
    cin>>m;
    while(m--){
        cin>>l>>r;
        cout<<query(1,l,r,1,n).X<<endl;
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/zhangxianlong/p/11568734.html