[NOIp2012提高组]借教室

OJ题号:洛谷1083

思路:ZKW线段树

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<algorithm>
 4 inline int getint() {
 5     char ch;
 6     while(!isdigit(ch=getchar()));
 7     int x=ch^'0';
 8     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
 9     return x;
10 }
11 const int N=1000001;
12 class ZKW {
13     #define _left <<1
14     #define _right <<1|1
15     private:
16         int m,val[N<<1],tag[N<<1];
17     public:
18         void build(const int n) {
19             for(m=1;m<=n;m<<=1);
20             for(int i=1;i<=n;i++) val[m+i]=getint();
21             for(int i=m;i;i--) val[i]=std::min(val[i _left],val[i _right]);
22         }
23         void modify(int l,int r,int x) {
24             for(l+=m-1,r+=m+1;l^r^1;l>>=1,r>>=1) {
25                 if(l<m) val[l]=std::min(val[l _left],val[l _right])-tag[l];
26                 if(~l&1) val[l^1]-=x,tag[l^1]+=x;
27                 if(r<m) val[r]=std::min(val[r _left],val[r _right])-tag[r];
28                 if(r&1) val[r^1]-=x,tag[r^1]+=x;
29             }
30             for(;l&&r;l>>=1,r>>=1) {
31                 val[l]=std::min(val[l _left],val[l _right])-tag[l];
32                 val[r]=std::min(val[r _left],val[r _right])-tag[r];
33             }
34         }
35         bool check() {
36             return val[1]>=0;
37         }
38 };
39 ZKW tree;
40 int main() {
41     int n=getint(),m=getint();
42     tree.build(n);
43     for(int i=1;i<=m;i++) {
44         int d=getint(),s=getint(),t=getint();
45         tree.modify(s,t,d);
46         if(!tree.check()) {
47             printf("-1\n%d\n",i);
48             return 0;
49         }
50     }
51     puts("0");
52     return 0;
53 }

 

posted @ 2017-06-28 20:32  skylee03  阅读(146)  评论(0编辑  收藏  举报