大致的思路是用线段树维护每个区间内部的最小值 段更新最小值 每次查某个区间的最小值是否满足租借要求 满足就借出去 update最小值
注意pushdown操作 还有一个从子区间提取答案的操作
提交地址 http://www.cogs.pro/cogs/problem/problem.php?pid=1266
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<vector> 5 #include<algorithm> 6 #define lson rt<<1 7 #define rson rt<<1|1 8 #define getmid int mid=(l+r)/2 9 using namespace std; 10 const int maxn=1100000; 11 12 int n,m,mins[maxn*4],tag[maxn*4],A[maxn]; 13 14 void pushdown(int rt) 15 { 16 if(tag[rt]!=0) 17 { 18 mins[rt]+=tag[rt]; 19 tag[lson]+=tag[rt]; 20 tag[rson]+=tag[rt]; 21 tag[rt]=0; 22 } 23 } 24 25 void bud(int l,int r,int rt) 26 { 27 if(l==r) { 28 mins[rt]=A[l]; 29 return; 30 } 31 getmid; 32 bud(l,mid,lson); 33 bud(mid+1,r,rson); 34 mins[rt]=min(mins[lson],mins[rson]); 35 } 36 37 int query(int l,int r,int rt,int a,int b) 38 { 39 pushdown(rt); 40 if(a<=l && b>=r) 41 { 42 return mins[rt]; 43 } 44 getmid; 45 int ans=1<<30; 46 if(a<=mid) ans=query(l,mid,lson,a,b); 47 if(b>mid) ans=min(ans,query(mid+1,r,rson,a,b)); 48 return ans; 49 } 50 51 void update(int l,int r,int rt,int a,int b,int c) 52 { 53 pushdown(rt); 54 if(a<=l && b>=r) 55 { 56 tag[rt]+=c; 57 return; 58 } 59 getmid; 60 if(a<=mid) update(l,mid,lson,a,b,c); 61 if(b>mid) update(mid+1,r,rson,a,b,c); 62 63 mins[rt]=min(mins[lson]+tag[lson],mins[rson]+tag[rson]); 64 65 } 66 67 68 int main() 69 { 70 freopen("classrooms.in","r",stdin); 71 freopen("classrooms.out","w",stdout); 72 scanf("%d%d",&n,&m); 73 for(int i=1;i<=n;i++) 74 { 75 scanf("%d",&A[i]); 76 } 77 bud(1,n,1); 78 79 80 for(int i=1,a,b,c;i<=m;i++) 81 { 82 scanf("%d%d%d",&a,&b,&c); 83 int tt=query(1,n,1,b,c); 84 if(tt>=a) 85 { 86 update(1,n,1,b,c,-a); 87 } 88 else 89 { 90 cout<<-1<<endl<<i; 91 return 0; 92 } 93 } 94 95 cout<<0; 96 fclose(stdin); 97 fclose(stdout); 98 return 0; 99 }