【题目】

D. Changing Array

【描述】

给n个整数a[1],...,a[n],满足0<=a[i]<=2^k-1。Vanya可以对这n个数中任一多个数进行操作,即将x变为x',其中x'指x限制在k位内二进制取反。问a[1],...,a[n]中最多有多少个连续子段的异或和不为0。

数据范围:1<=n<=200000,1<=k<=30

【思路】

为了叙述方便,记MAX=(1<<k)-1,即二进制下k位全是1的数。

为了符号表示不产生歧义,以下使用^表示异或(上面的题目描述中指的是次方)。

这里要用到异或运算的一个很重要的性质,即x^x=0。

根据定义,x^x'=MAX,从而x'=x^x^x'=x^MAX。

先不考虑a[1],...,a[n]的变化。维护前缀异或和s[i],于是a[i]^...^a[j]=s[j]^s[i-1]。那么,a[i]^...^a[j]==0当且仅当s[j]==s[i-1]。为了让连续子段异或和为0尽量少,就是要让s[i]尽量不同。

再看改变某个a[i]会带来的影响。将某个a[i]变为a[i]^MAX,那么包含a[i]的前缀异或和s[j]都要变为s[j]^MAX,即s[j]变为s[j]^MAX对所有j>=i。这个时候发现,如果再改变a[i+1],则s[k]又都变回去了对所有k>=i+1。这说明可以通过改变某些a[i]实现将某一个s[j]变为s[j]^MAX。

这个时候有个很自然的想法就是,值为x和x^MAX的那些s[i]应该放在一类中考虑,因为它们最多只有两个值,要想使得“在其中挑两个数,它们不相等”的概率最小,只能让取x和x^MAX的数字个数尽量平均,即相等或者相差1。

确定s[i]的取值之后(有多少个s[i]取某个值x或者x^MAX),记第k个取值的s[i]共有nk个,于是最终的答案为

注意:要注意取值范围,要开long long!【比赛中第一次提交就因为这个问题WA了……

【我的实现】

 1 #include <iostream>
2 #include <cstdio>
3 #include <cstring>
4 #include <cmath>
5 #include <algorithm>
6
7 using namespace std;
8 #define MaxN 200030
9
10 long long s[MaxN];
11
12 int main()
13 {
14 long long n, k;
15 long long i, j;
16 long long cnt, ans, tmp;
17 long long x;
18 long long MAX;
19 //scanf("%d%d", &n, &k);
20 cin >> n >> k;
21 MAX = (1<<(long long)k)-1;
22 s[0] = 0;
23 for(i = 1; i <= n; i++)
24 {
25 cin >> x;
26 s[i] = s[i-1] ^ x;
27 }
28 for(i = 0; i <= n; i++)
29 s[i] = min(s[i], MAX^s[i]);
30 sort(s, s+n+1);
31 cnt = 0;
32 ans = (n+1) * n / 2;
33 for(i = 0; i <= n; i++)
34 {
35 if(i == 0 || s[i] == s[i-1])
36 cnt++;
37 else
38 {
39 if(cnt % 2) //奇数
40 {
41 tmp = cnt / 2;
42 ans -= tmp * (tmp-1) / 2;
43 tmp = cnt / 2 + 1;
44 ans -= tmp * (tmp-1) / 2;
45 }
46 else
47 {
48 tmp = cnt / 2;
49 ans -= tmp * (tmp-1);
50 }
51 cnt = 1;
52 }
53 }
54 if(cnt % 2) //奇数
55 {
56 tmp = cnt / 2;
57 ans -= tmp * (tmp-1) / 2;
58 tmp = cnt / 2 + 1;
59 ans -= tmp * (tmp-1) / 2;
60 }
61 else
62 {
63 tmp = cnt / 2;
64 ans -= tmp * (tmp-1);
65 }
66 cout<< ans;
67 return 0;
68 }

【评测结果】

[题解]Mail.Ru Cup 2018 Round 1 - D. Changing Array的更多相关文章

  1. [题解]Mail.Ru Cup 2018 Round 1 - C. Candies Distribution

    [题目] C. Candies Distribution [描述] n个小朋友排排坐吃糖糖,小朋友从左到右编号1到n.每个小朋友手上有一定数量的糖.对于第i个小朋友来说,编号比他小的小朋友中有li个小 ...

  2. [题解]Mail.Ru Cup 2018 Round 1 - B. Appending Mex

    [题目] B. Appending Mex [描述] Ildar定义了一种方法,可以由一个数组产生一个数.具体地,从这个数组中任选一个子集,不在这个子集中的最小的非负整数称为mex,就是由这个数组得到 ...

  3. [题解]Mail.Ru Cup 2018 Round 1 - A. Elevator or Stairs?

    [题目] A. Elevator or Stairs? [描述] Masha要从第x层楼去第y层楼找Egor,可以选择爬楼梯或者坐直升电梯.已知爬楼梯每层需要时间t1:坐直升电梯每层需要时间t2,直升 ...

  4. [codeforces Mail.Ru Cup 2018 Round 3][B Divide Candies ][思维+数学]

    https://codeforces.com/contest/1056/problem/B 题意:输入n,m    求((a*a)+(b*b))%m==0的(a,b)种数(1<=a,b<= ...

  5. 【Mail.Ru Cup 2018 Round 2 A】 Metro

    [链接] 我是链接,点我呀:) [题意] [题解] 1:一直往右走的情况. 2:中间某个地方中转 (不会出现超过1次的转弯. (如果超过了和1次是等价的 [代码] #include <bits/ ...

  6. 【Mail.Ru Cup 2018 Round 2 B】 Alice and Hairdresser

    [链接] 我是链接,点我呀:) [题意] [题解] 因为只会增加. 所以. 一开始暴力算出来初始答案 每次改变一个点的话. 就只需要看看和他相邻的数字的值就好. 看看他们是不是大于l 分情况增加.减少 ...

  7. 【Mail.Ru Cup 2018 Round 2 C】 Lucky Days

    [链接] 我是链接,点我呀:) [题意] [题解] 题解的作者: manish_joshi 对于任意一个k 因为那条直线(关于x,y的方程可以看出一条直线)的斜率>= 所以肯定会经过第一象限. ...

  8. Mail.Ru Cup 2018 Round 2 C. Lucky Days(拓展欧几里得)

    传送门 待参考资料: [1]:https://www.cnblogs.com/Patt/p/9941200.html •题意 a君,b君存在幸运周期: a君在第[ L1+k·t1,R1+k·t1]天为 ...

  9. Mail.Ru Cup 2018 Round 3 B. Divide Candies

    题目链接 分析一下题意可以得到题目要求的是满足下面这个 公式的不同的i,ji,ji,j的方案数; 即(i2+j2)mod&ThinSpace;&ThinSpace; m=0 (n ≤  ...

随机推荐

  1. 记录python2.7迁移到python3.6过程中的一些代码差异

    python2.7 python 3.6 import urllib2 import urllib import urlparse import urllib import exceptions 废弃 ...

  2. Ajax的IE缓存问题

    Ajax之IE缓存问题 <!-- IE浏览器会对ajax的结果进行一个缓存,这样就会导致一个缓存问题 浏览器会读取缓存 而不会去使用一个新的数据 这样对一个时效性比较强的场景 ajax的缓存会影 ...

  3. 使用 fail2ban 保护 frp 服务

    背景 我们一般会使用 fail2ban 来保护暴露到公网的提供密码登录的 ssh 连接等. 但使用 frp 穿透后所有的从外网访问都会变成 127.0.0.1 进入的,原本能用 fail2ban 保护 ...

  4. 从数组中找出第K大的数

    利用改进的快排方法 public class QuickFindMaxKValue { public static void main(String[] args) { int[] a = {8, 3 ...

  5. golang中如何将json文件解析成结构体

    package tool import ( "bufio" "encoding/json" "fmt" "os" ) t ...

  6. Water 2.5 发布,一站式服务治理平台

    Water(水孕育万物...) Water 为项目开发.服务治理,提供一站式解决方案(可以理解为微服务架构支持套件).基于 Solon 框架开发,并支持完整的 Solon Cloud 规范:已在生产环 ...

  7. 删除文件行末尾的^M符号方法

    有时发现某些文件的末尾总是带有^M符号 cat /etc/hosts.allow|col -b > /etc/hosts.allow.old

  8. kubernetes之Pod水平自动伸缩(HPA)

    https://k8smeetup.github.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/ Horizon ...

  9. 实用的linux 命令

    1. 查看当前文件夹下文件或文件夹所占磁盘的大小 du -sh *|sort -rh 2. 查找某个进程号,脚本或程序所在目录的方法 ll /proc/进程id 3. awk 的用法 (1)累加: a ...

  10. AWS SAA_C01 考试分享。

    Saa-c01 经验分享! 序言1.介绍自己的情况,我是一个做后台开发的初级java程序员.还是处于在写业务逻辑的阶段,我对aws可谓是啥都不懂,纯种的小白,完全是从0基础开始学习的.希望分享一些我的 ...