您的位置:首页 > 其它

codevs 1191 数轴染色

2016-03-25 23:11 387 查看

1191 数轴染色

时间限制: 1 s

空间限制: 128000 KB

题目等级 : 黄金 Gold

题目描述 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

代码:

/*基本思路:利用线段树的区间操作,把叶节点都设为1,更改的时候设置为0,就可以了*/
#include<iostream>
using namespace std;
#include<cstdio>
struct node{
long long int l,r,val;
node *child[2];
int delta;
}*root=NULL;
int n,m,a,b;
void update(node *cur)
{
cur->val=cur->child[0]->val+cur->child[1]->val;
}
void bulid(node *&cur,int l,int r)
{
if(l>r) return ;
cur=new node;
cur->l=l;cur->r=r;
cur->delta=1;
if(l==r)
{
cur->child[0]=cur->child[1]=NULL;
cur->val=1;/*设置为1,表示一个叶节点是一个黑点*/
return;
}
int mid=(l+r)/2;
bulid(cur->child[0],l,mid);
bulid(cur->child[1],mid+1,r);
update(cur);/*统计出了每个区间的黑点数*/
}
void down(node *cur)/*标志的下传*/
{
cur->child[0]->val=cur->child[0]->delta=cur->child[1]->val=cur->child[1]->delta=0;
}
void change(node *cur,int l,int r)
{
if(l<=cur->l&&cur->r<=r)
{
cur->val=0;
cur->delta=0;/*给子区间的标志*/
return;
}
if(!cur->delta) down(cur);/*必不可少的必不可少的成分,一开始没过去就是因为这个地方,当把这个区间val赋值为0时,他的子区间没有修改,下次访问他的子区间,会得出错误答案,所以设置一个懒惰标志,用来下传*/
int mid=(cur->l+cur->r)/2;
if(l<=mid) change(cur->child[0],l,r);
if(r>mid) change(cur->child[1],l,r);
update(cur);
}
/*long long int query(node *cur,int l,int r)
{
if(l<=cur->l&&cur->r<=r)
{
cout<<cur->val<<endl;
return cur->val;
}
int ans=0;
int mid=(cur->l+cur->r)/2;
if(l<=mid) ans+=query(cur->child[0],l,r);
if(r>mid) ans+=query(cur->child[1],l,r);
cout<<ans<<endl;
return ans;
}
一开始写错的程序,题目求的是1--n的黑点数,而不是
指定区间的,指定区间的始终是0的。*/
int main()
{
scanf("%d%d",&n,&m);
bulid(root,1,n);
for(int i=1;i<=m;++i)
{
scanf("%d%d",&a,&b);
change(root,a,b);
printf("%lld\n",root->val);
}
return 0;
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: