codevs 1191 数轴染色
题目描述 Description
在一条数轴上有N个点,分别是1~N。一开始所有的点都被染成黑色。接着
我们进行M次操作,第i次操作将[Li,Ri]这些点染成白色。请输出每个操作执行后
剩余黑色点的个数。
输入描述 Input Description
输入一行为N和M。下面M行每行两个数Li、Ri
输出描述 Output Description
输出M行,为每次操作后剩余黑色点的个数。
样例输入 Sample Input
10 3
3 3
5 7
2 8
样例输出 Sample Output
9
6
3
数据范围及提示 Data Size & Hint
数据限制
对30%的数据有1<=N<=2000,1<=M<=2000
对100%数据有1<=Li<=Ri<=N<=200000,1<=M<=200000
分类标签 Tags 点此展开
思路:水题,区间修改,单点查询。
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define MAXN 200010 using namespace std; int n,m; struct nond{ int l,r,dis,flag; }tree[MAXN*4]; void up(int now){ tree[now].dis=tree[now*2].dis+tree[now*2+1].dis; } void build(int now,int l,int r){ tree[now].l=l;tree[now].r=r;tree[now].flag=0; tree[now].dis=tree[now].r-tree[now].l+1; if(tree[now].l==tree[now].r) return ; int mid=(tree[now].l+tree[now].r)/2; build(now*2,l,mid); build(now*2+1,mid+1,r); up(now); } void down(int now){ tree[now*2].flag=1;tree[now*2+1].flag=1; tree[now*2].dis=0;tree[now*2+1].dis=0; tree[now].flag=0; } void change(int now,int l,int r){ if(tree[now].l==l&&tree[now].r==r){ tree[now].dis=0;tree[now].flag=1; return ; } if(tree[now].flag) down(now); int mid=(tree[now].l+tree[now].r)/2; if(r<=mid) change(now*2,l,r); else if(l>mid) change(now*2+1,l,r); else { change(now*2,l,mid); change(now*2+1,mid+1,r); } up(now); } int main(){ scanf("%d%d",&n,&m); build(1,1,n); for(int i=1;i<=m;i++){ int x,y;scanf("%d%d",&x,&y); change(1,x,y);printf("%d\n",tree[1].dis); } }
细雨斜风作晓寒。淡烟疏柳媚晴滩。入淮清洛渐漫漫。
雪沫乳花浮午盏,蓼茸蒿笋试春盘。人间有味是清欢。