# G. Count the Trains
link : https://codeforces.com/contest/1690/problem/G
tóm tắt đề : đề dài vcl đíu biết tóm tắt ntn cho nó gọn nữa
cho mảng a, lập mảng b bằng cách lấy b[i] = min(a[1], a[i]), có m truy vấn, mỗi truy vấn trừ a[i] đi d đơn vị, hỏi có bao nhiêu giá trị khác nhau trong mảng b.
ý tưởng : dùng seg tree + lazy
code AC :
:::spoiler
```cpp
#include<bits/stdc++.h>
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define rev(i, a, b) for (int i = (a); i >= (b); --i)
#define ll long long
using namespace std;
const int mxn = 1e5 + 7;
struct node
{
int l, r, diff;
}seg[4*mxn];
int n, m;
int laz[4*mxn], a[mxn], b[mxn];
void build(int l, int r, int p)
{
if (l == r)
{
seg[p].diff = 1;
seg[p].l = seg[p].r = b[l];
return;
}
int mid = (l + r)>>1;
int L = (p << 1), R = L + 1;
build(l, mid, L);
build(mid + 1, r, R);
seg[p].diff = seg[L].diff + seg[R].diff;
if (seg[L].r == seg[R].l) --seg[p].diff;
seg[p].l = seg[L].l;
seg[p].r = seg[R].r;
}
void down(int p)
{
if (laz[p] == -1) return;
int L = (p << 1), R = L + 1;
seg[L].diff = 1;
seg[L].l = seg[L].r = laz[p];
laz[L] = laz[p];
seg[R].diff = 1;
seg[R].l = seg[R].r = laz[p];
laz[R] = laz[p];
laz[p] = -1;
}
int get(int l, int r, int p, int x)
{
if (l == r) return seg[p].l;
down(p);
int mid = (l + r)>>1;
if (x <= mid) return get(l, mid, p << 1, x);
else return get(mid + 1, r, (p << 1) + 1, x);
}
void update(int l, int r, int L, int R, int p, int val)
{
if (r < L || R < l) return;
if (L <= l && r <= R)
{
seg[p].diff = 1;
seg[p].l = seg[p].r = val;
laz[p] = val;
return;
}
down(p);
int mid = (l + r)>>1;
update(l, mid, L, R, p << 1, val);
update(mid + 1, r, L, R, (p << 1) + 1, val);
int Le = (p << 1), Ri = Le + 1;
seg[p].diff = seg[Le].diff + seg[Ri].diff;
if (seg[Le].r == seg[Ri].l) --seg[p].diff;
seg[p].l = seg[Le].l;
seg[p].r = seg[Ri].r;
}
int fi(int x)
{
int l = x, r = n;
while (l < r)
{
int mid = (l + r)/2 + 1;
if (get(1, n, 1, mid) < a[x]) r = mid - 1;
else l = mid;
}
return l;
}
int main(){
//freopen("D:\\test.txt", "r", stdin);
//freopen("D:\\test2.txt", "w", stdout);
int t; cin >> t;
while(t--)
{
scanf("%d%d", &n, &m);
rep(i, 1, n) scanf("%d", &a[i]);
int mi = b[1] = a[1];
rep(i, 2, n) mi = b[i] = min(mi, a[i]);
//rep(i, 1, n) cout << b[i] << ' '; return 0;
build(1, n, 1);
memset(laz, -1, sizeof(laz));
rep(i, 1, m)
{
int x, d;
scanf("%d%d", &x, &d);
a[x] -= d;
if (a[x] < get(1, n, 1, x))
{
//cout << a[x] << ' ' << get(1, n, 1, x) << "dd\n";
update(1, n, x, fi(x), 1, a[x]);
}
printf("%d ", seg[1].diff);
}
printf("\n");
}
}
```
:::
bug ngu : fill mảng laz = 0, quên là các giá trị lazy xuống cũng có thể = 0 nữa