[Hailiang training solution to a problem && && distribution segment tree farm]

Subject description:

armer John recently built a new farm, and cows are receiving an allocation request corral, corral will see some wonderful scenery Farm.

Farm by the N (1 <= N <= 100,000) composed of a stall, numbered 1 ... N, i can accommodate up to corral cows C_i (1 <= C_i <= 100,000). I want continuous cow stall period, expressed as period interval (A_i, B_i). In this case cows wandering in the bullpen this inside. (Of course, this corral must have enough space)

Given M (1 <= M <= 100,000) request, a request without exceeding the stall carrying capacity, the number of requests to meet up.

Consider a farm presented below:

No. 12345

Capacity | 1 | 3 | 2 | 1 | 3 |

Cow 1 (1, 3)

Cow 2 (2, 5)

3 cows (2, 3)

4 cows (4, 5)

FJ can not satisfy the request of four cows, or 3,4 corral will have too many cows.

Considering the need to request an interval of 2 cows Nos. 3 and 4 containing the corral, we tried a scheme, so that the request 1,3,4 cows are satisfied, so that there is no stall exceed the limit capacity, and therefore, is the answer to the above 3, requires three cows (1,3,4) can be met.


analysis:

First, a range of issues to see, think of a similar topic segments covered - greed came out
Made in Each cow will wander within a range, that is within each range will add 1, which is the range of change, seeking and problem - tree line came out

So this question is just a fence can tell us how much each cow, and did not tell us the number of cattle within a range, then we will convert:
the number of cattle there is a range of up to a range that is within the fence least the number of cattle that can exist
this is very obvious, so after this idea came out, the whole are good questions to do

Obviously segment covered greedy, press the right endpoint sorted
and then find the minimum number of cattle in the time interval achievements, it is very simple.
Every time into a cow, it queries the minimum value within this range is> = 1, that is, whether the query cattle:
if> = 1, indicating possible, ans ++, during the interval change
or not

So the whole idea is so above


Code

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m,ans=0;
bool f=1;
struct tree{
     int l,r,sum,tag,zl;
}tr[5000000];
struct node{
    int l,r;
}a[2000000];
int zl[2000000];

bool mycmp(node x,node y){
    return x.r<y.r;
}

void build(int p,int l,int r){
    tr[p].l=l,tr[p].r=r;
	if (l==r) {tr[p].zl=zl[l];return;}
	int mid=l+r>>1;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r); 
	tr[p].zl=min(tr[p*2].zl,tr[p*2+1].zl);//求最小值
}


int sum(int p,int x,int y){
    int l=tr[p].l,r=tr[p].r;
    if (l>y||r<x) return 100000000000;//如果出去了
    if (x<=l && y>=r) return tr[p].zl;//全部包含
    if (tr[p].tag){
	    tr[p*2].tag+=tr[p].tag;
	    tr[p*2].zl+=tr[p].tag;
	    tr[p*2+1].tag+=tr[p].tag;
	    tr[p*2+1].zl+=tr[p].tag;
	    tr[p].tag=0;
	}//向下传送懒标记
	return min(sum(p*2,x,y),sum(p*2+1,x,y));//返回
}

void change(int p,int x,int y){
    int l=tr[p].l,r=tr[p].r;
    if (l>y||r<x) return;
    if (x<=l && y>=r){
	    --tr[p].tag;
	    --tr[p].zl;
	    return;
	}//包含,就减去
	if (tr[p].tag){
	    tr[p*2].tag+=tr[p].tag;
	    tr[p*2].zl+=tr[p].tag;
	    tr[p*2+1].tag+=tr[p].tag;
	    tr[p*2+1].zl+=tr[p].tag;
	    tr[p].tag=0;
	}//传递
	change(p*2,x,y);
	change(p*2+1,x,y);
	tr[p].zl=min(tr[p*2].zl,tr[p*2+1].zl);//重新去最小值
	return;
}

signed main(){
	freopen("balloc.in","r",stdin);
	freopen("balloc.out","w",stdout);
    scanf("%lld %lld",&n,&m);
    for (int i=1;i<=n;i++) scanf("%lld",&zl[i]);
    for (int i=1;i<=m;i++)
      scanf("%lld %lld",&a[i].l,&a[i].r);
    sort(a+1,a+m+1,mycmp);//排序
    build(1,1,n);//建树
    for (int i=1;i<=m;i++)
      if (sum(1,a[i].l,a[i].r)) ans++,change(1,a[i].l,a[i].r);//如果返回的值>0
    printf("%lld",ans);
    return 0;
}

Please support me

Guess you like

Origin blog.csdn.net/huang_ke_hai/article/details/94720968