#二分,差分数组#SSL 2366 洛谷 1083 借教室

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sugar_free_mint/article/details/84073346

题目

问第几个区间加一会使区间内值超过限定值


分析

那么这道题需要用二分答案,然后同时用差分数组判断即可,时间复杂度 O ( n l o g m ) O(nlogm)


代码

#include <cstdio>
#define rr register
using namespace std;
struct rec{int d,l,r;}a[1000001];
int n,m,rest[1000001],t[1000001];
inline signed iut(){
    rr int ans=0; rr char c=getchar();
    while (c<48||c>57) c=getchar();
    while (c>47&&c<58) ans=(ans<<3)+(ans<<1)+c-48,c=getchar();
    return ans;
}
inline signed check(int x){
    for (rr int i=1;i<=n;++i) t[i]=0;
    for (rr int i=1;i<=x;++i) t[a[i].l]+=a[i].d,t[a[i].r+1]-=a[i].d;//是不是长得很像树状数组
    for (rr int i=1;i<=n;++i){
        t[i]+=t[i-1];
        if (t[i]>rest[i]) return 0;//超过那么答案肯定不是这个值
    }
    return 1;
}
signed main(){
    n=iut(); m=iut();
    for (rr int i=1;i<=n;++i) rest[i]=iut();
    for (rr int i=1;i<=m;++i) a[i]=(rec){iut(),iut(),iut()};
    if (check(m)) return !putchar(48);
    rr int l=1,r=m-1; 
    while (l<r){
        rr int mid=l+r>>1;
        if (check(mid)) l=mid+1;//答案必然更大
        else r=mid;//缩小查找区间
    }
    return !printf("-1\n%d",l); 
}

猜你喜欢

转载自blog.csdn.net/sugar_free_mint/article/details/84073346
今日推荐