NOIP2012 借教室 (線段樹)
阿新 • • 發佈:2019-02-07
Solution
考慮用線段樹維護,每借一段時間的教師便線上段樹中減去對應的值,不理解為什麼網上這麼多二分的。。
Code
//Author: Hany01
//Date: Nov 5th. 2017
#include<bits/stdc++.h>
#define For(i , j , k) for (int i = (j) , i##_end_ = (k) ; i <= i##_end_ ; ++ i)
#define Fordown(i , j , k) for (int i = (j) , i##_end_ = (k) ; i >= i##_end_ ; -- i)
#define Set(a , b) memset(a , b , sizeof(a))
#define lc (t << 1)
#define rc (lc | 1)
#define mid ((l + r) >> 1)
#define pb push_back
#define INF (0x3f3f3f3f)
#define Mod (1000000007)
using namespace std;
typedef long long LL;
template <typename T> inline bool chkmax(T &a , T b) { return a < b ? (a = b , 1) : 0; }
template <typename T> inline bool chkmin(T &a , T b) { return b < a ? (a = b , 1) : 0; }
int _ , __;
char c_;
inline int read()
{
for (_ = 0 , __ = 1 , c_ = getchar() ; !isdigit(c_) ; c_ = getchar()) if (c_ == '-') __ = -1;
for ( ; isdigit(c_) ; c_ = getchar()) _ = (_ << 1 ) + (_ << 3) + (c_ ^ 48);
return _ * __;
}
inline void File()
{
#ifdef hany01
freopen("classroom.in" , "r" , stdin);
freopen("classroom.out" , "w" , stdout);
#endif
}
const int maxn = 1000010;
int tr[maxn << 2], addv[maxn << 2], n, m, dt, x, y;
inline void maintain(int t) { tr[t] = min(tr[lc], tr[rc]); }
inline void pushdown(int t)
{
if (!addv[t]) return ;
tr[lc] += addv[t]; tr[rc] += addv[t]; addv[lc] += addv[t]; addv[rc] += addv[t]; addv[t] = 0;
}
void build(int t, int l, int r)
{
if (l == r) { tr[t] = read(); return; }
build(lc, l, mid); build(rc, mid + 1, r);
maintain(t);
}
void update(int t, int l, int r)
{
if (x <= l && r <= y) { tr[t] += dt; addv[t] += dt; return; }
pushdown(t);
if (x <= mid) update(lc, l, mid);
if (y > mid) update(rc, mid + 1, r);
maintain(t);
}
int main()
{
File();
n = read(); m = read();
build(1, 1, n);
For(Case, 1, m)
{
dt = -read(); x = read(); y = read();
update(1, 1, n);
if (tr[1] < 0) { printf("-1\n%d\n", Case); return 0; }
}
puts("0");
return 0;
}
//靜夜四無鄰,荒居舊業貧。
//雨中黃葉樹,燈下白頭人。
//以我獨沉久,愧君相見頻。
//平生自有分,況是霍家親。
//--司空曙《喜見外弟盧綸見宿》