[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 }