洛谷P3760异或和
传送门啦
传送门啦
一般这种位运算的题都要把每一位拆开来看,因为位运算每个位的结果这和这一位的数有关。
这样我们用s[i]表示a的前缀和,即 $ a[1]+a[2]+....a[i] $ ,然后我们从这些数二进制最右位 $ 2^0 $ 开始,按照每一位对答案的贡献来计算。
假设我们现在算到最右位 $ 2^0 $ ,并且位于第i个数,我们想要知道以i结尾的连续和对答案的贡献,只需要知道有多少 $ s[i]-s[j](0<=j<i)$ 的 $ 2^0 $ 位是1。 (设s[0]=0)
如果这个数是奇数,就说明异或了1奇数次,也就相当于异或了1,我们只需要把记录这一位总的异或贡献的变量 $ cnt $ 异或1即可;
如果是偶数就不用管了,对答案没有贡献。
对于数的每一位如果最后 $ cnt=1 $ 的话,就说明在这一位所有连续和的异或和为1,我们就需要把答案加上(1<<(这个位数))。
那如何快速计算有多少个 $ s[i]-s[j] $ 的二进制第k位是否为1呢??
答案是利用权值树状数组。
考虑到 $ \sum a $ 最大才有1000000,我们构造两棵权值树状数组,一棵记录当前位为1的,另一棵记录为0的。
如果当前扫描到的 $ s[i] $ 的二进制第k位为1,那么对这一位的答案有贡献的只有那些第k位为1且第k位向右的数比 $ s[i] $ 第k位向右的数大的或者第k位为0且第k位向右的数不比 $ s[i] $ 第k位向右的数大的。
因为如果第k位都为1的话,那么只有后面那些位的和大于s[i]的数, $ s[i] $ 减去它之后第k位才能出现1(因为s[i]比它小的话需要向更高位借数,就和小学学的横式减法差不多),从而对答案作出贡献;
如果第k位为0的话,如果后面再比 $ s[i] $ 大的话, $ s[i] $ 第k位的1就需要借给低一位的了,所以后面必须不比 $ s[i] $ 大。
这样就很好用权值树状数组维护了。。。。
include
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
#define max(a,b) (a)>(b)?(a):(b)
using namespace std;
const int maxn = 1e6 + 4;
inline int read() {
char ch = getchar();
int f = 1 , x = 0;
while(ch > '9' || ch < '0') {
if(ch == '-')f = -1;
ch = getchar();
}
while(ch >= '0' && ch <= '9') {
x = (x << 1) + (x << 3) + ch - '0';
ch = getchar();
}
return x * f;
}
ll s[maxn],a[maxn];
ll f[2][maxn],n,m,ans=0,now,cnt=0,tmp;
bool flag;
ll maxx;
inline int lowbit(int x){return x & (-x);}
inline void update(ll x,ll y) {
for(; x<=1000000; x+=lowbit(x))
f[y][x]++;
}
inline ll query(ll x,ll y) {
ll ansd = 0;
for(; x; x-=lowbit(x))
ansd += f[y][x];
return ansd;
}
int main() {
n = read();
for(ll i=1; i<=n; i++){
s[i] = read();
s[i] += s[i - 1];
maxx = max(maxx , s[i]);
}
for(ll i=0; i<=20; i++) {
if((1 << i) > maxn) break;
memset(f , 0 , sizeof(f));
flag = 0 , cnt = 0;
update(1 , 0);
for(ll j=1; j<=n; j++) {
tmp = s[j] & (1 << i);
if(tmp) now = query(a[j] + 1 , 0) + query(1000000 , 1) - query(a[j] + 1 , 1);
else now = query(a[j] + 1 , 1) + query(1000000 , 0) - query(a[j] + 1 , 0);
if(now % 2 ) cnt ^= 1;
update(a[j] + 1 , (tmp > 0 ? 1 : 0));
a[j] |= tmp;
}
if(cnt) ans += (1 << i);
}
cout<<ans;
return 0;
}
洛谷P3760异或和的更多相关文章
- 洛谷 P3908 异或之和
洛谷 P3908 异或之和 题目描述 求1⨁2⨁⋯⨁N 的值. A⨁B 即 AA, B 按位异或. 输入输出格式 输入格式: 1 个整数 N . 输出格式: 1 个整数,表示所求的值. 输入输出样例 ...
- 洛谷P3760 - [TJOI2017]异或和
Portal Description 给出一个\(n(n\leq10^5)\)的序列\(\{a_n\}(\Sigma a_i\leq10^6)\),求该数列所有连续和的异或和. Solution 线段 ...
- 洛谷——P3909 异或之积
P3909 异或之积 题目描述 对于A_1,A_2,A_3,\cdots,A_NA1,A2,A3,⋯,AN,求 (6\times \sum_{i=1}^N\sum_{j=i+1}^N\sum_ ...
- 洛谷——P3908 异或之和
P3908 异或之和 题目描述 求1 \bigoplus 2 \bigoplus\cdots\bigoplus N1⨁2⨁⋯⨁N 的值. A \bigoplus BA⨁B 即AA , BB 按位异或. ...
- 洛谷—— P3908 异或之和
https://www.luogu.org/problemnew/show/P3908 题目描述 求1 \bigoplus 2 \bigoplus\cdots\bigoplus N1⨁2⨁⋯⨁N 的值 ...
- 洛谷 P3909 异或之积 题解
原题链接 本人看了其它解法,发现本人的解法还是 首创 ! 而且我的解法好像和 \(\times 6\) 没什么关系 -- (如果没 \(\times 6\),我没还不用算逆元) 别人的思路呢,大都是从 ...
- 洛谷.5283.[十二省联考2019]异或粽子(可持久化Trie 堆)
LOJ 洛谷 考场上都拍上了,8:50才发现我读错了题=-= 两天都读错题...醉惹... \(Solution1\) 先求一遍前缀异或和. 假设左端点是\(i\),那么我们要在\([i,n]\)中找 ...
- 「洛谷5283」「LOJ3048」「十二省联考2019」异或粽子【可持久化01trie+优先队列】
题目链接 [洛谷传送门] [LOJ传送门] 题目大意 让你求区间异或和前\(k\)大的异或和的和. 正解 这道题目是Blue sky大佬教我做的(祝贺bluesky大佬进HA省A队) 我们做过某一些题 ...
- ⌈洛谷4735⌋⌈BZOJ3261⌋最大异或和【可持久化01Trie】
题目链接 [BZOJ传送门] [洛谷传送门] 题解 终于学会了可持久化trie树了.感觉并不是特别的难. 因为可持久化,那么我们就考虑动态开点的trie树. 都知道异或操作是有传递性的,那么我们就维护 ...
随机推荐
- SenseTime Ace Coder Challenge 暨 商汤在线编程挑战赛 E. 疯狂计数
1.改高精度 :float/double的精度为x位,小数部分最多x+x位(乘法和加法),整数部分<1000000*1000000/2=5 * 10^11 2.分成整数部分和小数部分分别存储,貌 ...
- python基础3--字符串
字符串 1.大小写转换 >>> name 'bigberg' >>> name.capitalize() # 首字母大写 'Bigberg' >>> ...
- python基础之面向对象01
什么是面向对象? 所谓面向对象就是将那些具有共同特质的事物组成一个类(Class),在类中为这些特质定义一个个方法(函数). 具体一点,比如说英雄联盟.在英雄联盟中我们可以把所有的英雄划分为一个英雄类 ...
- mysql 同步数据到 ElasticSearch 的方案
MySQL Binlog 要通过 MySQL binlog 将 MySQL 的数据同步给 ES, 我们只能使用 row 模式的 binlog.如果使用 statement 或者 mixed forma ...
- redis内存模型
前言 Redis是目前最火爆的内存数据库之一,通过在内存中读写数据,大大提高了读写速度,可以说Redis是实现网站高并发不可或缺的一部分. 我们使用Redis时,会接触Redis的5种对象类型(字符串 ...
- Java 多线程实现
第一种方式 package demo3; public class Threddemo { public static void main(String[] args) { MyThred mt = ...
- 用代码从文件中导入数据到SQL Server
引言 导入数据到SQL Server 是常见的需求,特别是定期导入这种需求. 对于定期导入主要有以下几种方式可选择: Bulk Insert Bcp Utility OpenRowSet 写程序导入( ...
- Tomcat与Spring中的事件机制详解
最近在看tomcat源码,源码中出现了大量事件消息,可以说整个tomcat的启动流程都可以通过事件派发机制串起来,研究透了tomcat的各种事件消息,基本上对tomcat的启动流程也就有了一个整体的认 ...
- 编程语言BrainkFuck
BrainFuck由Urban Müller在1993年创建,是经常被吐槽的语言,不过我觉得除了名字其它都还挺正常的,没错我觉得这个语言设计的很正常没有Fuck到我的脑子,大概是因为我根本就没有脑子吧 ...
- 33、Map简介
Map接口概述 除了Collection之外,常用的集合还有Map接口,里面常用的实现类图如下: map中的元素是以键-值的方式存在的,通过键可以获取到值,键是不可以重复的,跟地图比较像,通过一个坐标 ...