链接:Miku
---------------
这道题可以帮你深入了解懒标记的意义
----------------
蒟蒻本来想通过蒟蒻做法做的,就是种树就在位置+1,砍了-1,然而发现这样做会砍掉不存在的树
---------------
然而懒标记这个东西,为什么一定要是加或减呢?标记成这个区间需要修改成什么也可以呀
一开始的种树,就相当于把整个区间赋值为1,而砍树,就相当于把这个区间赋值为0了
这样用线段树解决就很明显了
------------------
#include<iostream> #include<cstdio> #include<algorithm> int n,m; long long sum[400005], lazy[400005]; int f,x,y; long long k; void pushdown(int x, int L, int R){ if (lazy[x] != -1){//把整个区间赋值为懒标记的值 int mid = (L + R) >> 1; lazy[x << 1] = lazy[x]; lazy[x << 1 | 1] = lazy[x];//下放与更新 sum[x << 1] = lazy[x] * (mid - L + 1); sum[x << 1 | 1] = lazy[x] * (R - mid); lazy[x] = -1; } return; } void pushup(int x){ sum[x] = sum[x << 1] + sum[x << 1 | 1]; return; } void update(int x, int l, int r, int L, int R, long long d){ if (L <= l && r <= R){//懒标记的新意义 lazy[x] =d; sum[x] = d * (r - l + 1); return; } int mid = (l + r) >> 1; pushdown(x, l, r); if (L <= mid) update(x << 1, l, mid, L, R, d); if (R > mid) update(x << 1 | 1, mid + 1, r, L, R, d); pushup(x); } long long query(int x, int l, int r, int L, int R){ if (L <= l && r <= R){ return sum[x]; } int mid = (l + r) >> 1; pushdown(x, l, r); long long ans = 0; if (L <= mid) ans += query(x << 1, l, mid, L, R); if (R > mid) ans += query(x << 1 | 1, mid + 1, r, L, R); return ans; } int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=400005;++i)//因为是0和1两种状态,所以不能是0 lazy[i]=-1; for(int i=0;i<=n;++i){ update(1, 0, n, i, i, 1);//种树?全赋值为一呗 } for(int i=1;i<=m;++i){ scanf("%d%d",&x,&y); update(1, 0, n, x, y, 0);//砍树,全赋值为零呗 } printf("%lld ", query(1, 0, n, 0, n)); return 0; }