P1083 [NOIP2012 提高组] 借教室

暴力的话,就是两重循环,然后挨个去判断能不能满足,复杂度(O(mn)),过不了

思路:二分答案,对于二分到的一个值x,去检查能否满足前x个(包括x)订单,如果能满足,说明前y(y<x)个订单都可以满足,所以可以二分到最大的可以满足的订单,但是题目要的是第一个不能满足的订单,所以需要在二分过程中记答案,另外判断能不能满足前x个订单,需要用差分和前缀和...

#include<iostream>
using namespace std;

const int N = 1000010;

struct node{
    int d, l, r;
}c[N];

int n, m;
int a[N], b[N];

int check(int x){
    for(int i = 1; i <= n; i ++) b[i] = a[i] - a[i - 1];
    for(int i = 1; i <= x; i ++) b[c[i].l] -= c[i].d, b[c[i].r + 1] += c[i].d;
    for(int i = 1; i <= n; i ++) if((b[i] += b[i - 1]) < 0) return 0;
    return 1;
}

int main(){
    cin >> n >> m;
    
    for(int i = 1; i <= n; i ++) cin >> a[i];
    for(int i = 1; i <= n; i ++) cin >> c[i].d >> c[i].l >> c[i].r;
    
    int ans = -1;
    int l = 1, r = m;
    while(l < r){
        int mid = l + r + 1 >> 1;
        if(check(mid)) l = mid;
        else{
            r = mid - 1;
            ans = mid;
        }
    }
    
    if(!check(l)) ans = l;
    
    if(~ans){
        puts("-1");
        cout << ans << endl;
        return 0;
    }
    
    puts("0");
    
    return 0;
}
原文地址:https://www.cnblogs.com/tomori/p/15275493.html