E. Vasya and Good Sequences
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Vasya has a sequence $$$a$$$ consisting of $$$n$$$ integers $$$a_1, a_2, \dots, a_n$$$. Vasya may pefrom the following operation: choose some number from the sequence and swap any pair of bits in its binary representation. For example, Vasya can transform number $$$6$$$ $$$(\dots 00000000110_2)$$$ into $$$3$$$ $$$(\dots 00000000011_2)$$$, $$$12$$$ $$$(\dots 000000001100_2)$$$, $$$1026$$$ $$$(\dots 10000000010_2)$$$ and many others. Vasya can use this operation any (possibly zero) number of times on any number from the sequence.

Vasya names a sequence as good one, if, using operation mentioned above, he can obtain the sequence with bitwise exclusive or of all elements equal to $$$0$$$.

For the given sequence $$$a_1, a_2, \ldots, a_n$$$ Vasya'd like to calculate number of integer pairs $$$(l, r)$$$ such that $$$1 \le l \le r \le n$$$ and sequence $$$a_l, a_{l + 1}, \dots, a_r$$$ is good.

Input

The first line contains a single integer $$$n$$$ ($$$1 \le n \le 3 \cdot 10^5$$$) — length of the sequence.

The second line contains $$$n$$$ integers $$$a_1, a_2, \dots, a_n$$$ ($$$1 \le a_i \le 10^{18}$$$) — the sequence $$$a$$$.

Output

Print one integer — the number of pairs $$$(l, r)$$$ such that $$$1 \le l \le r \le n$$$ and the sequence $$$a_l, a_{l + 1}, \dots, a_r$$$ is good.

Examples
Input
3
6 7 14
Output
2
Input
4
1 2 1 16
Output
4
Note

In the first example pairs $$$(2, 3)$$$ and $$$(1, 3)$$$ are valid. Pair $$$(2, 3)$$$ is valid since $$$a_2 = 7 \rightarrow 11$$$, $$$a_3 = 14 \rightarrow 11$$$ and $$$11 \oplus 11 = 0$$$, where $$$\oplus$$$ — bitwise exclusive or. Pair $$$(1, 3)$$$ is valid since $$$a_1 = 6 \rightarrow 3$$$, $$$a_2 = 7 \rightarrow 13$$$, $$$a_3 = 14 \rightarrow 14$$$ and $$$3 \oplus 13 \oplus 14 = 0$$$.

In the second example pairs $$$(1, 2)$$$, $$$(2, 3)$$$, $$$(3, 4)$$$ and $$$(1, 4)$$$ are valid.

题意
对于任何一个$$$a_i$$$,可以将其表示为$$$2$$$进制并任意更改它里面1的位置。对于区间[l,r],如果对其中一些数执行任意次这样的操作,从而使得区间的异或和为0,就称这段区间是good。给$$$n$$$个数,$$$1\le a_i\le 10^{18}$$$,求有多少个子区间是good。
分析
异或和只与二进制中$$$1$$$的个数有关,所以用$$$b_i$$$记录$$$(a_i)_2$$$中的$$$1$$$的个数,形成一个新的数组$$$b[n]$$$,之后就不再考虑数组$$$a[n]$$$了。
为了方便叙述,用$$$x\oplus y$$$表示对$$$x,y$$$进行任意调整后,可能的异或值的集合。容易发现两个数的情况($$$x\lt y$$$),结果是一个公差为2的等差序列:
$$$$$$
\begin{align}
x\oplus y=\{|y-x|,\ |y-x|+2,\ ...,\ x+y \}
\end{align}
$$$$$$
三个数的情况($$$x\lt y\lt z$$$),结果也是公差为2的等差序列:
$$$$$$
\begin{align}
x\oplus y\oplus z=\{min\{|z-t|,\ t\in x\oplus y\},\ ...,\ x+y+z \}
\end{align}
$$$$$$
分析可以发现,区间可能的异或值的范围,上限是区间和,下限是一个小于最大元素的数,要判断异或值能否为0,最暴力的方法,就是把$$$min\{...\}$$$里面遍历一遍,看0是不是在其中,而这需要很大的代价。
有一个更好的解决办法,注意到上限是一个很容易维护的值,而下限一定小于区间的最大元素,假设$$$[l,r]$$$内最大和第二大的数分别为$$$b_i,\ b_j$$$,把$$$b_i$$$单独拿出来,剩下的数形成新的区间,那么新区间的上限就是的新的区间和,下限就是一个小于$$$b_j$$$的数,所以下限一定小于$$$b_i$$$。要让原区间下限为0,就转而去判断新区间对应的等差序列中有没有$$$b_i$$$,因为如果有,就可以抵消掉,从而原区间的下限就是0。具体的来说,$$$b_i$$$要在其中,要满足两个条件:
【1】上限大于或等于$$$b_i$$$;
【2】$$$b_i$$$与上限同奇偶;
这样一来,通过上限就能确定区间是否为good,完全避免了对下限的考虑了。但是单独把$$$b_i$$$提出来还是很麻烦,不如把条件转化为对整个区间的限制:
【1】区间和大于或等于最大元素的两倍;
【2】区间和是偶数;
还有一个性质,$$$b_i$$$的范围是1~63,也就意味着,只要区间的长度不小于64,区间和≥63+$$$b_i$$$≥$$$2b_i$$$,就一定满足条件【1】,所以只用考虑所有长度小于64的区间,于是问题的规模就缩小到了64n,就变成了一个使劲码就能做出来的题了。
一种比较好的写法是,先算求和为偶数的区间的总个数,再遍历所有长度小于64且和为偶数的区间,从总个数中去掉不满足条件的,剩下的个数就是答案。
总结
分析问题眼光还是不够敏锐啊。结合了官方题解+拜读大佬的代码,整理出这样一个还算完整的思路,花了一晚上。什么时候才能在比赛中,独立做出这样的题呢。
代码
#include<stdio.h>
typedef long long LL;
int cnt(LL x) {
int res = ;
while (x)res += x & , x >>=;
return res;
}
int b[]={},fre[];
LL ai;
int cnt0 = , cnt1 = ;
int main(){
int n;
scanf("%d", &n);
for(int i=;i<=n;++i) {
scanf("%I64d", &ai); b[i] = cnt(ai); fre[i] = fre[i - ] + b[i];
if (fre[i] & )cnt1++;
else cnt0++;
}
/*求和为偶数的区间个数:
*
*对于前缀和为奇数的[0,l1], [0,l2], ..., [0,lcnt1]
* 对l1而言,它和后面的组合起来,[l1+1,l2], [l1+1,l3], ..., [l1+1,lcnt1]的和一定全都是偶数
* l2~lcnt1也同理,共cnt1-1+cnt1-2+...1=cnt1(cnt1-1)/2个
*
* 对于和为偶数的区间[0,r1], [0, r2], ..., [0,rcnt0]
*
* 不仅和奇数的相同,每个区间本身也要加入计数
* 所以共cnt0+cnt0-1+...+1=(cnt0+1)cnt0/2个
*/
LL ans = 1LL * cnt1*(cnt1 - ) / +1LL*cnt0*(cnt0+)/; //遍历所有以i为起点的区间
for(int i=;i<=n;++i) {
int maxn = ,sum;
//只检查到长度为64
for(int j=;j<=&&i+j<=n;++j){
if (maxn < b[i + j])maxn = b[i + j];
sum = fre[i + j] - fre[i - ];
if ((sum & ) == && (maxn<<) > sum)ans--;
}
}
printf("%I64d", ans);
}

codeforces 1041 E.Vasya and Good Sequences(暴力?)的更多相关文章

  1. Codeforces 1053 B - Vasya and Good Sequences

    B - Vasya and Good Sequences 思路: 满足异或值为0的区间,必须满足一下条件: 1.区间中二进制1的个数和为偶数个; 2.区间二进制1的个数最大值的两倍不超过区间和. 如果 ...

  2. Codeforces #550 (Div3) - G.Two Merged Sequences(dp / 贪心)

    Problem  Codeforces #550 (Div3) - G.Two Merged Sequences Time Limit: 2000 mSec Problem Description T ...

  3. [CF1030E]Vasya and Good Sequences

    [CF1030E]Vasya and Good Sequences 题目大意: 给定一个长度为\(n(n\le3\times10^5)\)的数列\(a_i(1\le a_i\le10^{18})\). ...

  4. codeforces 1041 e 构造

    Codeforces 1041 E 构造题. 给出一种操作,对于一棵树,去掉它的一条边.那么这颗树被分成两个部分,两个部分的分别的最大值就是这次操作的答案. 现在给出一棵树所有操作的结果,问能不能构造 ...

  5. [Codeforces 1053B] Vasya and Good Sequences

    Link: Codeforces 1053B 传送门 Solution: 其实就是暴力 观察需要满足的条件: 1.个数和为偶数 2.最大个数不大于其它所有个数的和 如果只有第一个条件记录前缀和的奇偶性 ...

  6. Codeforces Round #512 (Div. 2, based on Technocup 2019 Elimination Round 1) E. Vasya and Good Sequences(DP)

    题目链接:http://codeforces.com/contest/1058/problem/E 题意:给出 n 个数,对于一个选定的区间,区间内的数可以通过重新排列二进制数的位置得到一个新的数,问 ...

  7. Codeforces Round #262 (Div. 2) A. Vasya and Socks【暴力/模拟/袜子在可以在合法情况下增加后用几天】

    A. Vasya and Socks time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  8. [Codeforces 1058E] Vasya and Good Sequences

    [题目链接] https://codeforces.com/contest/1058/problem/E [算法] 显然 , 我们只需考虑序列中每个数的二进制表示下1的个数即可. 不妨令Ai表示第i个 ...

  9. Codeforces Round #512 E - Vasya and Good Sequences

    有时候觉得自己就是个思路搬运机,只会搬运思路 这个题首先说了求的是好区间的个数,  好区间满足条件: 1.二进制位1的数量和为偶数    2.w[i]表示a[i]的二进制上1的个数 ,sum[i] = ...

随机推荐

  1. BootStap学习笔记(1)

    移动设备优先:  为了让开发的网站对移动设备友好,确保适当的绘制和触屏缩放,需要在网页的head之中添加viewport meat标签:如下: <metaname="viewport& ...

  2. Linux shell 编写(2)

    shell脚本中变量的定义和使用: 1.shell中变量名可以由字母,数字,下划线组成,但数字不能作为变量名的第一个字符. 2.通过赋值符号"="来定义一个变量 如:myname= ...

  3. ecCodes 学习 利用ecCodes Python API对GRIB文件进行读写

    参考 https://www.ecmwf.int/assets/elearning/eccodes/eccodes2/story_html5.htmlhttps://confluence.ecmwf. ...

  4. ffmpeg——关于视频压缩

    这篇博客主要讲有关于视频压缩的问题,解决视频文件太大,不便于下载,占用存储空间过大等问题,在缩小视频大小的同时,保证视频的观看质量.主要讲以下几点: 1.压缩视频工具ffmpeg 2.压缩视频的技术参 ...

  5. python-分叉树枝

    import turtle def draw_branch(length): #绘制右侧树枝 if length >5: if length == 10: turtle.pencolor('gr ...

  6. ubuntu 相关软件设置

    软件篇 1. 网易云音乐软件 首先去官网下载网易云音乐客户端linux版,网址:http://music.163.com/#/download,选择linux版本,然后选择ubuntu 16.04(6 ...

  7. windows 无法链接 \\ , 拼写错误或者网络有问题,解决方法

    1. 楼主首先在网上搜索了一遍问题, 比较全面的回答链接如下http://blog.csdn.net/newizan/article/details/50313137 然而并没有解决问题, 于是反思了 ...

  8. jenkins展示report测试报告的配置

    HTML报告展示 1. 需要HTML Publisher plugin插件 2. 在workspace下的工程(构建)中的目录中存储测试报告 在Jenkins中新建一个job,进入配置项. 首先通过p ...

  9. bing词典vs有道词典对比测试报告——功能篇之细节与用户体验

    之所以将细节与用户体验放在一起讨论,是因为两者是那么的密不可分.所谓“细节决定成败”,在细节上让用户感受方便.舒适.不费心而且温馨,多一些人文理念,多一些情怀,做出来的产品自然比其他呆板的产品更受欢迎 ...

  10. 【Alpha发布】贡献分分配

    最后贡献分分配: (1211)王嘉豪:32 (1186)黄雨萌:36 (1182)佘彦廷:40 (1208)何小松:50 (1200)鲁聃:62 (1174)邢浩:64 (1193)刘乾:66