题目:戳这里

题意:两个数n,k,满足给的n个数小于2的k次方。每个数可以进行一次操作,即把a[i]换成a[i]^(1<<k-1);求最多的连续区间数使得 区间[L,R] (1<=L<=R<=n),满足: a[L] ^ a[L+1] ^ … ^ a[R-1] ^ a[R] != 0

解题思路:

首先我们知道n个数可构成的连续区间是n*(n+1)/2个,如果一个一个找肯定会超时,需要一种能快速算出[L,R]区间异或和的方法。因为异或满足交换法则。所以a[1]^a[2]^...^a[L-1] ^ a[1]^a[2]^...^a[R]=a[L]^a[L+1]^...^a[R];也就是只要纪录前缀异或和,就可以快速算出每个区间的异或值。

设前缀异或和为s[],maxx=1<<k-1。

因为相等的值相互异或为0,所以只要s[L]==s[R],则[L,R]区间的异或和为0. 此外,假设对a[i]进行一次异或操作得a[i]'=a[i]^maxx,则s[i]'=s[i]^maxx,因为异或满足s[i]^maxx^maxx=s[i],所以对于s[]数组,每进行两次^maxx的操作,当前的前缀值s[i]就相当于没有进行操作。

这样问题就转化为,经过无数次操作后,使得s[]数组中相等的数尽量的少,就可以用贪心解决了。

用map<ll,ll>mp维护每个值出现的次数。计算前缀和s[i]值时,决策s[i]=mp[s[i-1]]>mp[s[i-1]^maxx]?s[i-1]^maxx:mp[s[i-1]];用基础的组合知识(确定L,R两端点便可以确定一个区间)就可以算出最终答案。

附ac代码:

 1 #include <bits/stdc++.h>
2 using namespace std;
3 typedef long long ll;
4 const int maxn = 2e5 + 10;
5 const ll mod = 998244353;
6 ll a[maxn];
7 int main() {
8
9 ll n, k;
10 scanf("%lld %lld", &n, &k);
11 for(int i = 1; i <= n; ++i) {
12 scanf("%lld", &a[i]);
13 }
14 ll ans = ll((n + 1) * n / 2);
15 ll maxx = 1ll;
16 maxx = (maxx << k) - 1ll;
17 map<ll,ll> mp;
18 mp[0] = 1;
19 ll now = 0;
20 for(ll i = 1; i <= n; ++i) {
21 now ^= a[i];
22 now = mp[now]>mp[now ^ maxx]?now^maxx:now;
23 ans -= mp[now];//组合数Cn2
24 mp[now]++;
25 }
26 printf("%lld\n", ans);
27 return 0;
28 }

1054D Changing Array 【位运算+思维】的更多相关文章

  1. Codeforces Round #716 (Div. 2), problem: (B) AND 0, Sum Big位运算思维

    & -- 位运算之一,有0则0 原题链接 Problem - 1514B - Codeforces 题目 Example input 2 2 2 100000 20 output 4 2267 ...

  2. 【洛谷4424】[HNOI/AHOI2018] 寻宝游戏(位运算思维题)

    点此看题面 大致题意: 给你\(n\)个\(m\)位二进制数.每组询问给你一个\(m\)位二进制数,要求你从\(0\)开始,依次对于这\(n\)个数进行\(and\)或\(or\)操作,问有多少种方案 ...

  3. codeforces 245 D. Restoring Table(位运算+思维)

    题目链接:http://codeforces.com/contest/245/problem/D 题意:给出一个矩阵b,b[i][j]=a[i]&a[j],b[i][i]=-1.然后求a[i] ...

  4. luogu 4366 [Code+#4]最短路 Dijkstra + 位运算 + 思维

    这个题思路十分巧妙,感觉很多题都有类似的套路. 我们发现异或操作其实就是将一个数的二进制的若干个 $0$ 变成 $1$,或者一些 $1$ 变成 $0$. 而每次按照某种顺序一位一位地异或也可以起到同时 ...

  5. Codeforces 1054D Changing Array 贪心+异或和

    题意 给一个长度为\(n\)的位数为\(k\)的整数数列\(a\),一次操作可将任意\(a_i\)取反,问经过任意次操作后最多有多少个区间异或和不为\(0\) 分析 求出前缀异或和,区间异或和为\(0 ...

  6. ZOJ 3870:Team Formation(位运算&思维)

    Team Formation Time Limit: 2 Seconds Memory Limit: 131072 KB For an upcoming programming contest, Ed ...

  7. Codeforces Round #672 (Div. 2) B. Rock and Lever题解(思维+位运算)

    题目链接 题目大意 给你一个长为n(n<=1e5)的数组,让你求有多少对a[i]和a[j] (i!=j)满足a[i]&a[j]>a[i]^a[j] 题目思路 这些有关位运算的题目肯 ...

  8. Divide by Zero 2021 and Codeforces Round #714 (Div. 2) B. AND Sequences思维,位运算 难度1400

    题目链接: Problem - B - Codeforces 题目 Example input 4 3 1 1 1 5 1 2 3 4 5 5 0 2 0 3 0 4 1 3 5 1 output 6 ...

  9. [题解]Mail.Ru Cup 2018 Round 1 - D. Changing Array

    [题目] D. Changing Array [描述] 给n个整数a[1],...,a[n],满足0<=a[i]<=2^k-1.Vanya可以对这n个数中任一多个数进行操作,即将x变为x' ...

随机推荐

  1. js reduce数组转对象

    借鉴:https://juejin.im/post/5cfcaa7ae51d45109b01b161#comment这位大佬的处理方法很妙,但是我一眼看过去没有明白,细细琢磨了下,终于明白了 1 co ...

  2. 登陆到 SAP 系统后的用户出口

    增强类型:smod 增强名称:SUSR0001 组件(退出功能模块):EXIT_SAPLSUSF_001 功能:用户每次登陆SAP系统后都会调用这个SUSR0001增强,可以在FUNCTION EXI ...

  3. 一个非常棒的Go-Json解析库

    json是一种数据格式,经常被用作数据交换,页面展示,序列化等场景,基本每种语言都有对应的json解析框架,Go语言也不例外,并且内置了json库,基本能够满足一些普通开发场景,但有些复杂场景下就不太 ...

  4. Linux服务器内存池技术是如何实现的

    Linux服务器内存池技术是如何实现的

  5. 数据库内核——基于HLC的分布式事务实现深度剖析

    DTCC 2019 | 深度解码阿里数据库实现 数据库内核--基于HLC的分布式事务实现深度剖析-阿里云开发者社区 https://developer.aliyun.com/article/70355 ...

  6. Obligations for calling close() on the iterable returned by a WSGI application

    Graham Dumpleton: Obligations for calling close() on the iterable returned by a WSGI application. ht ...

  7. 洛谷P6218

    感觉此题是P4317 花神的数论题的变形版 Description 求一段区间内二进制中 \(0\) 的个数不小于 \(1\) 的个数的数的个数 Solution 数位 DP 先考虑状态转移方程式,如 ...

  8. LOJ10090

    题目描述 原题来自:USACO 2005 Dec. Gold FJ 有 n 头奶牛(2<=n<=1000) ,编号为1..n .奶牛们将按照编号顺序排成一列队伍(可能有多头奶牛在同一位置上 ...

  9. 数据分析中常用的Excel函数

    数据分析中excel是一个常见且基础的数据分析工具,要想掌握好它,学会使用其中的常用函数是一个绕不过去的坎.从网上搜集的资料来说,基本上确定了数据分析中Excel的常用函数有以下这六类 数学函数:SU ...

  10. 1.二层常用技术-STP

    1.STP定义: STP(Spanning Tree Protocol)是生成树协议的英文缩写.STP在IEEE 802.1D文档中定义,该协议的原理是按照树的结构来构造网络拓扑,消除网络中的环路,避 ...