P1083 [NOIP2012 提高组] 二分 + 差分

题意

传送门 P1083 [NOIP2012 提高组] 借教室

题解

二分答案,问题转化为判定第 1 − m i d 1-mid 1mid 个请求是否得到满足。使用差分,将 [ s i , t i ] [s_i,t_i] [si,ti] 上减去 d i d_i di 的区间修改转化为单点修改,最后求前缀和,判断是否存在空闲房间数为负的情况即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 1000005;
int N, M, R[maxn], D[maxn], S[maxn], T[maxn], df[maxn];
ll sum[maxn];

inline int read()
{
    
    
    int x = 0;
    char c = 0;
    for (; c < '0' || c > '9'; c = getchar())
        ;
    for (; c >= '0' && c <= '9'; c = getchar())
        x = (x << 1) + (x << 3) + c - '0';
    return x;
}

bool judge(int p)
{
    
    
    for (int i = 1; i <= N; ++i)
        sum[i] = df[i];
    for (int i = 1; i <= p; ++i)
        sum[S[i]] -= D[i], sum[T[i] + 1] += D[i];
    for (int i = 1; i <= N; ++i)
        if ((sum[i] += sum[i - 1]) < 0)
            return 0;
    return 1;
}

int main()
{
    
    
    N = read(), M = read();
    for (int i = 1; i <= N; ++i)
        R[i] = read();
    for (int i = 1; i <= M; ++i)
        D[i] = read(), S[i] = read(), T[i] = read();
    df[1] = R[1];
    for (int i = 2; i <= N; ++i)
        df[i] = R[i] - R[i - 1];
    int lb = 0, ub = N + 1;
    while (ub - lb > 1)
    {
    
    
        int mid = (lb + ub) >> 1;
        if (judge(mid))
            lb = mid;
        else
            ub = mid;
    }
    if (ub == N + 1)
        puts("0");
    else
        printf("-1\n%d\n", ub);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/neweryyy/article/details/114445710
今日推荐