luogu1083 [NOIp2012]借教室 (二分答案+差分)
先二分一个答案x,然后通过差分来看有没有不满足的
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define lowb(x) ((x)&(-(x))) 4 #define REP(i,n0,n) for(i=n0;i<=n;i++) 5 #define PER(i,n0,n) for(i=n;i>=n0;i--) 6 #define MAX(a,b) ((a>b)?a:b) 7 #define MIN(a,b) ((a<b)?a:b) 8 #define CLR(a,x) memset(a,x,sizeof(a)) 9 #define rei register int 10 using namespace std; 11 typedef long long ll; 12 const int maxn=1e6+5; 13 14 inline ll rd(){ 15 ll x=0;char c=getchar();int neg=1; 16 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 17 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 18 return x*neg; 19 } 20 21 int N,M,ask[maxn][3]; 22 int num[maxn],cnt[maxn]; 23 24 inline bool judge(int m){ 25 memset(cnt,0,sizeof(cnt)); 26 for(int i=1;i<=m;i++){ 27 cnt[ask[i][0]]+=ask[i][2],cnt[ask[i][1]+1]-=ask[i][2]; 28 } 29 for(int i=1,j=0;i<=N;i++){ 30 j+=cnt[i]; 31 if(j>num[i]) return 0; 32 }return 1; 33 } 34 35 int main(){ 36 //freopen(".in","r",stdin); 37 rei i,j,k; 38 N=rd(),M=rd(); 39 for(i=1;i<=N;i++) num[i]=rd(); 40 for(i=1;i<=M;i++){ 41 int a=rd(),b=rd(),c=rd(); 42 ask[i][0]=b,ask[i][1]=c,ask[i][2]=a; 43 } 44 int l=0,r=M,ans; 45 while(l<=r){ 46 int m=l+r>>1; 47 if(judge(m)) ans=m+1,l=m+1; 48 else ans=m,r=m-1; 49 } 50 if(ans>M) printf("0\n"); 51 else{ 52 printf("-1\n%d\n",ans); 53 } 54 return 0; 55 }