当前位置:首页 > 位运算 > 正文
SSOJ2276树状的灯
1960+

题目大意:n盏灯,可以进行区间关灯、开灯、取反操作,也可以查看有多少盏灯开着或者关着。

题目描述

校园里有一个古老的树,树上挂着n盏灯。这些灯围成了树的形状,很好看。现在,这n盏灯,有的的开着的,有的是关着的。开着用1来表示,关着用0来表示。当这些灯形成一个完美组合时,会非常非常好看。为了让这个树状的灯形成完美组合,小明打算对这些灯进行m个操作。小明可以对这些灯中的某些连续的灯进行关灯、开灯或者取反(开的灯关;关的灯开)操作,也可以数一下有多少盏灯是开着的,多少盏灯是关着的。请把数灯的结果输出来。

输入

第一行:输入一个正整数n和一个正整数m

第二行:一个只含有0和1的长度为n的字符串,表示编号为1到n的灯的状态

接下来m行,每行有1个数o或者3个数o,a,b,如果o是0,代表数一下有多少个关着的灯;如果o是1,代表数一下有多少个开着的灯;如果o是2,代表将编号为a到b的灯(含a和b)进行取反操作;如果o是3,代表将编号为a到b的灯(含a和b)进行开灯操作;如果o是4,代表将编号为a到b的灯(含a和b)进行关灯操作。

输出

对于数灯的操作结果,各输出一行。

样例输入

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

样例输出

3
4

提示

第一个操作:数开着的灯,共3个(3,4,5),输出3;

第二个操作:将第2-3之间的灯全部取反,得到01011

第三个操作:将第1-1之间的灯全部开灯,得到11011

第四个操作:将第4-5之间的灯全部关灯,得到10000

第五个操作:数关着的灯,共4个(2,3,4,5),输出4。

【数据范围】

50%的数据:n < 32,m < 100000

100%的数据:n < 64,m <= 1000000

解题思路

虽然是区间操作,但不一定用到线段树!因为区间很小,直接模拟就行了。这里讲一下怎么用位运算解决:至多63盏灯,可以用long long类型的变量x记录灯的状态;若灯开着,对应的二进制位为1,否则为0;数开着的灯,只要看一下数的二进制中有多少个1,每次减去-x&x或者&=x-1都可以;8盏灯区间2到4开灯,只需要|二进制下的00001110,取反则用异或运算符^;如果是关灯,就&11110001(~00001110=11110001)。

程序实现

About

坚决不Copy代码!

本文标签:,,,

SSOJ2276树状的灯:等您坐沙发呢!

发表评论

您必须 [ 登录 ] 才能发表留言!