1. 程式人生 > >#二分,差分陣列#SSL 2366 洛谷 1083 借教室

#二分,差分陣列#SSL 2366 洛谷 1083 借教室

題目

問第幾個區間加一會使區間內值超過限定值


分析

那麼這道題需要用二分答案,然後同時用差分陣列判斷即可,時間複雜度 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); }