[NOIP2012 提高组] 借教室

原题链接

一道二分+差分的题目,作为学习前缀和 和 差分 的引入题目非常合适。

首先检验其单调性,如果一个申请人订单不用修改,那么其前面的申请人也不用修改,符合单调性。

接着,这道题暴力的思路就很简单,但是看到运算量(n,m高达1e6),暴力的时间复杂度为O(n*m)显然超时。

那么就是运用差分思想了(不会的快去学!!)

主要代码:

#include<bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n;
int a[N],d[N],s[N],t[N];
long long differ[N];    //一定要long long 极端情况differ[i]高达1e6*1e9(m个d[i]之和)
bool check(int m){
    memset(differ,0,sizeof(differ));
    for (int i=1;i<=m;i++) {
        differ[s[i]]+=d[i];
        differ[t[i]+1]-=d[i];
    }
    for (int i=1;i<=n;i++){
        differ[i]+=differ[i-1];
        if (differ[i]>a[i]) return false;
    }
    return true;
}
int main(){
    ios::sync_with_stdio(false);
    int m;
    cin>>n>>m;
    for (int i=1;i<=n;i++) cin>>a[i];
    for (int j=1;j<=m;j++) cin>>d[j]>>s[j]>>t[j];
    int left=0,right=m+1;
    while (left+1<right){
        int mid=left+(right-left>>1);
        if (check(mid)) left=mid;
        else right=mid;
    }
    if (left==m) cout<<0<<"\n";
    else cout<<-1<<"\n"<<right<<"\n";
    return 0;
}

 

posted @ 2024-02-01 20:40  黑屿白  阅读(12)  评论(0编辑  收藏  举报