[NOIP2012]借教室

嘟嘟嘟

 

题解说是二分答案和前缀和,然而我愣是没看到……

但是这就是线段树板子题啊!

区间修改维护最小值,如果当前修改后的区间最小值小于0的话就说明这个订单无法完全满足。

竟然TLE了一个点,开氧气过了。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<cstdlib>
 7 #include<cctype>
 8 #include<stack>
 9 #include<queue>
10 #include<vector>
11 using namespace std;
12 #define enter puts("")
13 #define space putchar(' ')
14 #define Mem(a, x) memset(a, x, sizeof(a))
15 #define rg register
16 typedef long long ll;
17 typedef double db;
18 const int INF = 0x3f3f3f3f;
19 const db eps = 1e-8;
20 const int maxn = 1e6 + 5;
21 inline ll read()
22 {
23   ll ans = 0;
24   char ch = getchar(), las = ' ';
25   while(!isdigit(ch)) las = ch, ch = getchar();
26   while(isdigit(ch)) ans = (ans << 3) + (ans << 1) + ch - '0', ch = getchar();
27   if(las == '-') ans = -ans;
28   return ans;
29 }
30 inline void write(ll x)
31 {
32   if(x < 0) putchar('-'), x = -x;
33   if(x >= 10) write(x / 10);
34   putchar(x % 10 + '0');
35 }
36 
37 int n, m, a[maxn];
38 
39 int l[maxn << 2], r[maxn << 2], Min[maxn << 2], lzy[maxn << 2];
40 void build(int L, int R, int now)
41 {
42   l[now] = L; r[now] = R;
43   if(L == R) {Min[now] = read(); return;}
44   int mid = (L + R) >> 1;
45   build(L, mid, now << 1);
46   build(mid + 1, R, now << 1 | 1);
47   Min[now] = min(Min[now << 1], Min[now << 1 | 1]);
48 }
49 void pushdown(int now)
50 {
51   if(lzy[now])
52     {
53       Min[now << 1] += lzy[now];
54       Min[now << 1 | 1] += lzy[now];
55       lzy[now << 1] += lzy[now];
56       lzy[now << 1 | 1] += lzy[now];
57       lzy[now] = 0;
58     }
59 }
60 void update(int L, int R, int now, int d)
61 {
62   if(l[now] == L && r[now] == R)
63     {
64       Min[now] -=d; lzy[now] -= d;
65       return;
66     }
67   pushdown(now);
68   int mid = (l[now] + r[now]) >> 1;
69   if(R <= mid) update(L, R, now << 1, d);
70   else if(L > mid) update(L, R, now << 1 | 1, d);
71   else update(L, mid, now << 1, d), update(mid + 1, R, now << 1 | 1, d);
72   Min[now] = min(Min[now << 1], Min[now << 1 | 1]);
73 }
74 int query(int L, int R, int now)
75 {
76   if(L == l[now] && R == r[now]) return Min[now];
77   pushdown(now);
78   int mid = (l[now] + r[now]) >> 1;
79   if(R <= mid) return query(L, R, now << 1);
80   else if(L > mid) return query(L, R, now << 1 | 1);
81   else return min(query(L, mid, now << 1), query(mid + 1, R, now << 1 | 1));
82 }
83 
84 int main()
85 {
86   n = read(); m = read();
87   build(1, n, 1);
88   for(int i = 1; i <= m; ++i)
89     {
90       int d = read(), L = read(), R = read();
91       update(L, R, 1, d);
92       if(query(L, R, 1) < 0) {printf("-1\n%d\n", i); return 0;}
93     }
94   write(0); enter;
95   return 0;
96 }
View Code

 

posted @ 2018-09-28 17:40  mrclr  阅读(169)  评论(0编辑  收藏  举报