[유통 세그먼트 트리 농장 && && 문제에 Hailiang 교육 솔루션]

주제 설명 :

아머 존은 최근 새 팜을 구축하고, 소는 어떤 멋진 풍경 농장을 볼 수, 코랄 할당 요청 가축을 받고있다.

N 개의 양식장 (1 <= N <= 10)를 1 번째, 마구간 이루어지는 ... N, 난 젖소 C_I (1 <= C_I <= 100,000) 가축 위해 수용 할 수있다. I 연속 소 스톨 기간, 시간 간격 (A_I, B_i)로 표시 할. 이 경우 소는 불펜이 내부를 방황. (물론,이 가축 충분한 공간이 있어야합니다)

을 감안할 때 M (1 <= M <= 100,000) 요청, 운반 능력 스톨을 초과하지 않으면 요청은 요청의 수를 만날 수 있습니다.

아래에 제시 농장을 고려 :

번호 12345

용량 | 1 | 3 | 2 | 1 | 3 |

암소 1 (1, 3)

암소 2 (2, 5)

(3 개) 소 (2, 3)

소 4 (4, 5)

FJ는 4 개 개의 소의 요구를 만족시킬 수 없다, 또는 3,4 가축 너무 많은 소를해야합니다.

가축을 포함하는 2 개 소 호. (3)과 (4)의 간격을 요청할 필요성을 감안이 스킴을 시도하므로 요구한다는 실속 따라서 한계 용량을 초과하지 않으며,이 있도록 1,3,4 소, 만족, 위의 3에 대한 답이다, 세 개의 소 (1,3,4)을 충족시킬 수 있어야합니다.


분석 :

첫째, 문제의 범위가 덮여 유사한 주제 세그먼트의 생각, 볼 - 탐욕이 나왔다
범위 내에서 방황 각 소에서 만든, 그 추구하는 변화의 범위 (1)를 추가, 각 범위 내에 및 문제 - 트리 라인 나왔다

그래서이 질문은 단지 울타리가 얼마나 각 젖소 우리를 알 수 있으며, 범위 내에서 우리에게 가축의 수를 말하지 않았다, 우리는 변환합니다 :
가축의 수는 울타리 적어도 내에있는 범위까지의 범위가 존재할 수있는 가축의 수
이 매우 분명하다, 그래서이 아이디어가 나온 후, 전체가 할 수있는 좋은 질문입니다

분명히 세그먼트 오른쪽 엔드 포인트 정렬 욕심을 눌러 적용
후 시간 간격 성과 가축의 최소 수를 찾을 수를, 그것은 매우 간단합니다.
소로마다, 즉,이 범위 내의 최소값> = 1 쿼리 조회 소 여부 :
> = 1, 가능한 나타내는 ANS ++ 중에 간격 변경하면
아닌지

그래서 모든 생각은 너무 이상하다


암호

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

저를 지원하십시오

추천

출처blog.csdn.net/huang_ke_hai/article/details/94720968