CODEVS 1690 开关灯

题目描述 

    YYX家门前的街上有N(2<=N<=100000)盏路灯,在晚上六点之前,这些路灯全是关着的,六点之后,会有M(2<=m<=100000)个人陆续按下开关,这些开关可以改变从第i盏灯到第j盏灯的状态,现在YYX想知道,从第x盏灯到第y盏灯中有多少是亮着的(1<=i,j,x,y<=N)

输入描述

1 : 用空格隔开的两个整数NM

2..M+1 : 每行表示一个操作, 有三个用空格分开的整数: 指令号(0代表按下开关,1代表询问状态), x

输出描述 

1..询问总次数:对于每一次询问,输出询问的结果

样例输入 

4 5
0 1 2
0 2 4
1 2 3
0 2 4
1 1 4

样例输出 

1
2

数据范围及提示 

一共4盏灯,5个操作,下面是每次操作的状态(X代表关上的,O代表开着的)

XXXX -> OOXX -> OXOO -> 询问1~3 -> OOXX -> 询问1~4

题解:线段树模板题

#include <cstdio>
struct TREE{
	int l,r,sum;
	bool lazy;
}tree[400005];
int n,m,x,y,z;
using namespace std;
inline int read()          
{          
    int f=1,x=0;          
    char ch=getchar();          
    if (ch=='-')          
    {          
        f=-1;          
        ch=getchar();          
    }          
    while ((ch<'0')||(ch>'9')) ch=getchar();          
    while ((ch>='0')&&(ch<='9'))          
    {          
        x=x*10+ch-48;          
        ch=getchar();          
    }          
    return f*x;          
} 
inline void build(int root,int l,int r)
{
	tree[root].l=l;tree[root].r=r;
	if (l==r) return;
	build(root*2,l,(l+r)/2);
	build(root*2+1,(l+r)/2+1,r);
}
inline void push_down(int root,int l,int r)
{
	if (!tree[root].lazy) return;
	int mid=(l+r)/2;
	tree[root*2].sum=(mid-l+1)-tree[root*2].sum;
	tree[root*2].lazy=!tree[root*2].lazy;
	tree[root*2+1].sum=(r-mid)-tree[root*2+1].sum;
	tree[root*2+1].lazy=!tree[root*2+1].lazy;
	tree[root].lazy=0;
}
inline void change(int root,int l,int r)
{
	int ll=tree[root].l,rr=tree[root].r;
	int mid=(ll+rr)/2;
	if ((l<=ll)&&(rr<=r))
	{
		tree[root].sum=(rr-ll+1)-tree[root].sum;
		tree[root].lazy=!tree[root].lazy;
		return;
	}
	push_down(root,ll,rr);
	if (l<=mid) change(root*2,l,r);
	if (r>mid) change(root*2+1,l,r);
	tree[root].sum=tree[root*2].sum+tree[root*2+1].sum;
}
inline int find(int root,int l,int r)
{
	int ll=tree[root].l,rr=tree[root].r,s=0;
	int mid=(ll+rr)/2;
	if ((l<=ll)&&(rr<=r)) return tree[root].sum;
	push_down(root,ll,rr);
	if (l<=mid) s+=find(root*2,l,r);
	if (r>mid) s+=find(root*2+1,l,r);
	return s;
}
int main()
{
	n=read(),m=read();
	build(1,1,n);
	for (int i=1;i<=m;i++)
	{
		x=read(),y=read(),z=read();
		if (x==0) change(1,y,z); else
		  printf("%d\n",find(1,y,z));
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zhouhongkai06/article/details/80302794