您的位置:首页 > 其它

[Usaco2010 Mar]balloc 农场分配

2013-10-24 21:53 465 查看
Farmer John最近新建立了一个农场,并且正在接受奶牛的畜栏分配请求,有些

畜栏会看到农场美妙的风景。:)

农场由N (1 <= N <= 100,000) 个畜栏组成,编号为1..N,畜栏i可以最多容纳C_i只奶牛

(1 <= C_i <= 100,000)。奶牛i希望得到连续的一段畜栏,表示为一段区间 (A_i,B_i) 。

这样的话奶牛可以在这段牛棚里面转悠。(当然,这段畜栏必须要有足够的空间)

给出M (1 <= M <= 100,000) 个请求,请求出不超过畜栏承载量的情况下,最多可以满足的请求数。

具体做法就是

对请求,按照r关键字递增排序,然后r相同就按照l递减排序。

总的来讲就是优先截止早的区间,相同的话就优先区间长度小的区间。

然后一个一个请求往里塞,就是线段树操作了。能塞的塞进去,不能的就continue

每个位置有个权值代表剩余多少个空位。

对于一个区间覆盖时就看区间最小值是否大于0.

然后区间更新即可

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdlib>
#include <cmath>
#include <map>
#include <sstream>
#include <queue>
#include <vector>
#define MAXN 100005
#define MAXM 211111
#define eps 1e-8
#define INF 50000001
#define lch(x) x<<1
#define rch(x) x<<1|1
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
using namespace std;
int mi[MAXN * 4];
int cover[MAXN * 4];
struct node
{
int l, r;
}q[MAXN];
bool cmp(node x, node y)
{
if(x.r != y.r) return x.r < y.r;
return x.l > y.l;
}
int a[MAXN];
int n, m;
void up(int rt)
{
mi[rt] = min(mi[lch(rt)], mi[rch(rt)]);
}
void down(int rt)
{
if(cover[rt])
{
cover[lch(rt)] += cover[rt];
cover[rch(rt)] += cover[rt];
mi[lch(rt)] -= cover[rt];
mi[rch(rt)] -= cover[rt];
cover[rt] = 0;
}
}
void build(int l, int r, int rt)
{
if(l == r)
{
mi[rt] = a[l];
return;
}
int m = (l + r) >> 1;
build(lson);
build(rson);
up(rt);
}
int check(int L, int R, int l, int r, int rt)
{
if(L <= l && R >= r) return mi[rt];
down(rt);
int m = (l + r) >> 1;
int mi = INF;
if(L <= m) mi = min(mi, check(L, R, lson));
if(R > m) mi = min(mi, check(L, R, rson));
return mi;
}
void update(int L, int R, int l, int r, int rt)
{
if(L <= l && R >= r)
{
cover[rt] += 1;
mi[rt] -= 1;
return;
}
down(rt);
int m = (l + r) >> 1;
if(L <= m) update(L, R, lson);
if(R > m) update(L, R, rson);
up(rt);
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf("%d", &a[i]);
build(1, n, 1);
for(int i = 0; i < m; i++) scanf("%d%d", &q[i].l, &q[i].r);
sort(q, q + m, cmp);
int ans = 0;
for(int i = 0; i < m; i++)
{
if(check(q[i].l, q[i].r, 1, n, 1) > 0) ans++, update(q[i].l, q[i].r, 1, n, 1);
}
printf("%d\n", ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: