P1083 借教室(差分+二分)

 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 }
View Code

 

posted @ 2018-10-29 16:43  kafuuchino  阅读(117)  评论(0编辑  收藏  举报