P1083 借教室(差分+二分)
第一眼:线段树。
然鹅懒得写。
正解:差分+二分。
显然订单合法的上线可以二分
然后差分数组维护一下。没了。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cctype> 5 #define re register 6 using namespace std; 7 void read(int &x){ 8 char c=getchar();x=0; 9 while(!isdigit(c)) c=getchar(); 10 while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar(); 11 } 12 #define N 1000002 13 struct data{int c,l,r;}a[N]; 14 int n,m,q1,q2,c[N],s[N]; 15 bool check(int lim){ 16 memset(s,0,sizeof(s)); int tot=0; 17 for(re int i=1;i<=lim;++i) s[a[i].l]-=a[i].c,s[a[i].r+1]+=a[i].c;//差分数组2 18 for(re int i=1;i<=n;++i){ 19 tot+=s[i]+c[i]; 20 if(tot<0) return 0; 21 }return 1; 22 } 23 int main(){ 24 read(n);read(m); 25 for(re int i=1;i<=n;++i) read(q1),c[i]=q1-q2,q2=q1;//差分数组1 26 for(re int i=1;i<=m;++i) read(a[i].c),read(a[i].l),read(a[i].r); 27 if(check(m)) printf("0"); 28 else{ 29 int l=1,r=m; 30 while(l<r){ 31 int mid=l+((r-l)>>1); 32 if(check(mid)) l=mid+1; 33 else r=mid; 34 }printf("-1\n%d",l); 35 }return 0; 36 }