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;
}