# 题目描述

Farmer John recently opened up a new barn and is now accepting stall allocation requests from the cows since some of the stalls have a better view of the pastures.

The barn comprises N (1 <= N <= 100,000) stalls conveniently numbered 1..N; stall i has capacity C_i cows (1 <= C_i <= 100,000). Cow i may request a contiguous interval of stalls (A_i, B_i) in which to roam (1 <= A_i <= N; A_i <= B_i <= N), i.e., the cow would like to wander among all the stalls in the range A_i..B_i (and the stalls must always have the capacity for her to wander).

Given M (1 <= M <= 100,000) stall requests, determine the maximum number of them that can be satisfied without exceeding stall

capacities.

(1 ≤ Ai ≤ N; Ai ≤ Bi ≤ N)，换言之，这只牛想要在编号范围为Ai..Bi的畜栏漫步（所有它想要畜栏必须实施为它空出位置来供它散步）

畜栏号:    1   2   3   4   5
+---+---+---+---+---+

+---+---+---+---+---+
Cow 1       XXXXXXXXXXX             (1, 3)
Cow 2           XXXXXXXXXXXXXXX     (2, 5)
Cow 3           XXXXXXX             (2, 3)
Cow 4                   XXXXXXX     (4, 5)

## 输入输出样例

5 4
1
3
2
1
3
1 3
2 5
2 3
4 5

3

## 说明

Source: USACO 2010 March Gold

Translator: @chrome01

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>

using namespace std;

const int inf = 0x7ffffff;

int n,m,minn[300010],flag[300010],ans;
bool flag2 = false;

struct node
{
int a,b;
}e[100010];

bool cmp(node x,node y)
{
if (x.b != y.b)
return x.b < y.b;
else
return x.a > y.a;
}

void pushup(int o)
{
minn[o] = min(minn[o * 2],minn[o * 2 + 1]);
}

void pushdown(int o)
{
if (flag[o])
{
flag[o * 2] += flag[o];
flag[o * 2 + 1] += flag[o];
minn[o * 2] -= flag[o];
minn[o * 2 + 1] -= flag[o];
}
flag[o] = 0;
}

void build(int l,int r,int o)
{
if (l == r)
{
scanf("%d",&minn[o]);
return;
}
int mid = (l + r) >> 1;
build(l,mid,o * 2);
build(mid + 1,r,o * 2 + 1);
pushup(o);
}

void update(int l,int r,int o,int x,int y)
{
if (x <= l && r <= y)
{
flag[o]++;
minn[o]--;
return;
}
pushdown(o);
int mid = (l + r) >> 1;
if (x <= mid)
update(l,mid,o * 2,x,y);
if (y > mid)
update(mid + 1,r,o * 2 + 1,x,y);
pushup(o);
}

int query(int l,int r,int o,int x,int y)
{
if (x <= l && r <= y)
return minn[o];
pushdown(o);
int mid = (l + r) >> 1,res = inf;
if (x <= mid)
res = min(query(l,mid,o * 2,x,y),res);
if (y > mid)
res = min(query(mid + 1,r,o * 2 + 1,x,y),res);
return res;
}

int main()
{
scanf("%d%d",&n,&m);
build(1,n,1);
for (int i = 1; i <= m; i++)
scanf("%d%d",&e[i].a,&e[i].b);
sort(e + 1,e + 1 + m,cmp);
for (int i = 1; i <= m; i++)
{
if (query(1,n,1,e[i].a,e[i].b) <= 0)
continue;
update(1,n,1,e[i].a,e[i].b);
ans++;
}
printf("%d\n",ans);

return 0;
}

posted @ 2017-09-12 15:22 zbtrs 阅读(...) 评论(...) 编辑 收藏