【NOIP2012提高组】借教室

90分暴力解法:

用线段树,初始值为该天的教室数,每个人来申请的时候在这段区间减去借走的数,然后查询最小值是否小于0,是就输出-1,否则继续。

(其实在vijos是可以直接A的,他们的评测机太快了)

#include <iostream>
#define maxn 1000005
using namespace std;
void scan(int &x)
{
    char c;
    bool flag = false;
    while (!isdigit(c = getchar()))
    {
        if (c == '-')
            flag = true;
    }
    x = 0;
    do
        x = x * 10 + c - '0';
    while (isdigit(c = getchar()));
    if (flag)
        x = -x;
}
int n, m, val[maxn];
namespace seg
{
struct node
{
    int val, mark, minimum;
} nds[maxn * 4];
void init(int l = 1, int r = n, int p = 1)
{
    if (l == r)
    {
        nds[p].minimum = nds[p].val = val[l];
    }
    else
    {
        int mid = (l + r) / 2;
        init(l, mid, p * 2);
        init(mid + 1, r, p * 2 + 1);
        nds[p].minimum = min(nds[p * 2].minimum, nds[p * 2 + 1].minimum);
    }
}
void add(int l, int r, int val, int p = 1, int ll = 1, int rr = n)
{
    if (l == ll && r == rr)
    {
        nds[p].mark += val;
        nds[p].minimum += val;
    }
    else
    {
        int mid = (ll + rr) / 2;
        if (l <= mid)
            add(l, min(r, mid), val, p * 2, ll, mid);
        if (mid + 1 <= r)
            add(max(l, mid + 1), r, val, p * 2 + 1, mid + 1, rr);
        nds[p].minimum = min(nds[p * 2].minimum, nds[p * 2 + 1].minimum) + nds[p].mark;
    }
}
int query(int l, int r, int p = 1, int ll = 1, int rr = n)
{
    if (l == ll && r == rr)
    {
        return nds[p].minimum;
    }
    else
    {
        int mid = (ll + rr) / 2;
        int ans = 0x7fffffff;
        if (l <= mid)
            ans = min(ans, query(l, min(r, mid), p * 2, ll, mid));
        if (mid + 1 <= r)
            ans = min(ans, query(max(l, mid + 1), r, p * 2 + 1, mid + 1, rr));
        return ans + nds[p].mark;
    }
}
}
int main()
{
    ios::sync_with_stdio(false);
    scan(n);
    scan(m);
    for (int i = 1; i <= n; i++)
        scan(val[i]);
    seg::init(1,n,1);
    int d, s, t;
    for (int i = 1; i <= m; i++)
    {
        scan(d);
        scan(s);
        scan(t);
        seg::add(s, t, -d);
        if (seg::query(s, t) < 0)
        {
            cout << -1 << endl
                 << i;
            return 0;
        }
    }
    cout << 0;
    return 0;
}
原文地址:https://www.cnblogs.com/ssttkkl/p/7576994.html