codevs 1191 树轴染色 线段树区间定值,求和
codevs 1191 树轴染色
Time Limit: 1 Sec Memory Limit: 256 MB
题目连接
http://www.codevs.cn/problem/1191/Description
在一条数轴上有N个点,分别是1~N。一开始所有的点都被染成黑色。接着
我们进行M次操作,第i次操作将[Li,Ri]这些点染成白色。请输出每个操作执行后
剩余黑色点的个数。
我们进行M次操作,第i次操作将[Li,Ri]这些点染成白色。请输出每个操作执行后
剩余黑色点的个数。
Input
输入一行为N和M。下面M行每行两个数Li、Ri
Output
输出M行,为每次操作后剩余黑色点的个数。
Sample Input
10 3
3 3
5 7
2 8
3 3
5 7
2 8
Sample Output
9
6
3
6
3
HINT
数据限制
对30%的数据有1<=N<=2000,1<=M<=2000
对100%数据有1<=Li<=Ri<=N<=200000,1<=M<=200000
对30%的数据有1<=N<=2000,1<=M<=2000
对100%数据有1<=Li<=Ri<=N<=200000,1<=M<=200000
题意
题解:
区间更新,把黑色当成1,白色当成0,然后搞一搞就好了代码:
#include <stdio.h> #include <string.h> const int MAXN = 400000; int sum[MAXN<<2]; int lazy[MAXN<<2]; void pushup(int rt) { sum[rt] = sum[rt<<1] + sum[rt<<1|1]; } void pushdown(int rt, int x) { if(lazy[rt] != -1) { lazy[rt<<1] = lazy[rt<<1|1] = lazy[rt]; sum[rt<<1] = (x-(x>>1))*lazy[rt];///!!! sum[rt<<1|1] = (x>>1)*lazy[rt];///!!! lazy[rt] = -1; } } void creat(int l, int r, int rt) { lazy[rt] = -1, sum[rt] = 0; if(l == r) return; int mid = (l+r)>>1; creat(l, mid, rt<<1); creat(mid+1, r, rt<<1|1); pushup(rt); } void modify(int l, int r, int x, int L, int R, int rt) { if(l <= L && r >= R) { lazy[rt] = x; sum[rt] = x*(R-L+1);///!!! return; } pushdown(rt, R-L+1);///!!! int mid = (L+R)>>1; if(l <= mid) modify(l, r, x, L, mid, rt<<1); if(r > mid) modify(l, r, x, mid+1, R, rt<<1|1); pushup(rt); } int main() { int i, j, k = 0; int n, T, q; int x, y, w; //while(scanf("%d", &T) != EOF) //while(T--) //{ scanf("%d %d", &n, &q); creat(1, n, 1); while(q--) { scanf("%d %d", &x, &y); modify(x, y, 1, 1, n, 1); printf("%d\n",n-sum[1]); } //printf("Case %d: The total value of the hook is %d.\n", ++k, sum[1]); //} return 0; }