4017: 小Q的无敌异或

Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 593  Solved: 197
[Submit][Status][Discuss]

Description

背景
 
小Q学习位运算时发现了异或的秘密。
 
描述
 
小Q是一个热爱学习的人,他经常去维基百科(http://en.wikipedia.org/wiki/Main_Page)学习计算机科学。
 
就在刚才,小Q认真地学习了一系列位运算符(http://en.wikipedia.org/wiki/Bitwise_operation),其中按位异或的运算符 xor 对他影响很大。按位异或的运算符是双目运算符。按位异或具有交换律,即i xor j = j xor i。
 
他发现,按位异或可以理解成被运算的数字的二进制位对应位如果相同,则结果的该位置为0,否则为1,例如1(01) xor 2(10) = 3(11)。
 
他还发现,按位异或可以理解成数字的每个二进制位进行了不进位的加法,例如3(11) xor 3(11) = 0(00)。
 
于是他想到了两个关于异或的问题,这两个问题基于一个给定的非负整数序列A1, A2, ..., An,其中n是该序列的长度。
 
第一个问题是,如果用f(i, j)表示Ai xor Ai+1 xor ... xor Aj,则任意的1 <= i <= j <= n的f(i, j)相加是多少。
 
第二个问题是,如果用g(i, j)表示Ai + Ai+1 + ... + Aj,则任意的1 <= i <= j <= n的g(i, j)异或在一起是多少。
 
比如说,对于序列{1, 2},所有的f是{1, 2, 1 xor 2},加起来是6;所有的g是{1, 2, 1 + 2},异或起来是0。
 
他觉得这两个问题都非常的有趣,所以他找到了你,希望你能快速解决这两个问题,其中第一个问题的答案可能很大,你只需要输出它对998244353(一个质数)取模的值即可。
 

Input

第一行一个正整数n,表示序列的长度。
 
第二行n个非负整数A1, A2, ..., An,表示这个序列。
 

Output

两个整数,表示两个问题的答案,空格隔开,其中第一个问题的答案要对998244353(一个质数)取模。
 

Sample Input

2
1 2

Sample Output

6 0
 

此题求解该序列所有可能存在的子区间的异或和以及和的异或。
对于第一问求解区间的异或和。这一问在2017西安现场赛G题出现过,只不过把整个区间改为询问指定的区间。那么我们把每个数拆开,一位一位地来算贡献。在某一位上,我们做一个异或的前缀和,即把+换为^。那我们要求解某个区间[l,r]的异或值,即为sum(r)^sum(l-1)。包含0位置在内共有n+1个端点。我们统计下这个前缀和为1的端点数有k个,那么为0的就有(n+1-k)个,那么区间俩端点必须由不同数组成异或才为1(即sum(r)和sum(l-1)),这样的区间我们能选择k*(n+1-k),这即为第一问答案。
对于第二问。我们依旧拆开一位一位做。假如这是第k位,我们做%(2k+1)的前缀和。
如果第k位为1 ,那么(sum(r)−sum(l−1))mod 2k+1≥2k,这点显而易见。
用ans存这位是否为1,。我们从小到大枚举r,看满足这个等式的l-1是否为奇数个,如果是则ans^=1,否则不管。
但这东西不拆开来是不好做的。这个式子拆开 mod前的数并变换可以得出两个式子来限定sum(l-1)%(2k+1)的取值范围:
  1. sum(l−1)mod 2k+1≤(sum(r)mod2k+1)−2,0≤sum(l−1)mod2k+1 ,即 0≤sum(l−1)mod2k+1≤(sum(r)mod2k+1)−2k
  2. sum(l−1)mod2k+1≤(sum(r)mod2k+1)−2k+2k+1=(sum(r)mod2k+1)+2,sum(r)mod2k+1<sum(l−1)mod2k+1 ,即 sum(r)mod2k+1<sum(l−1)mod2k+1≤(sum(r)mod2k+1)+2

我们先离散化所有前缀和的值。在枚举r的过程中,然后看对应区间内的数量是不是奇数个,这个可以用^的树状数组实现。或者权值线段树实现。

这样枚举了右端点后,就能得出ans,若为1则加上相应的2的幂次方作为答案贡献。

 #include<bits/stdc++.h>
#define clr(x) memset(x,0,sizeof(x))
#define clr_1(x) memset(x,-1,sizeof(x))
#define LL long long
#define mod 998244353
using namespace std;
const int N=1e5+;
int bit[N];
LL a[N];
LL order[N],found[N];
int n,m,k,cnt;
LL ans1,ans2;
void qy1(int mp)
{
LL num=;
LL now=;
for(int i=;i<=n;i++)
{
now^=(a[i]>>mp)&;
if(now)
num++;
}
ans1=(ans1+num*(n-num+)%mod*(1LL<<mp)%mod)%mod;
return ;
}
void add(int i,int x)
{
if(!i) return ;
while(i<=cnt+)
{
bit[i]^=x;
i+= i&-i;
}
return ;
}
int sum(int i)
{
int res=;
while(i)
{
res^=bit[i];
i-= i&-i;
}
return res;
}
void qy2(int mp)
{
clr(bit);
int p;
found[]=order[]=;
for(int i=;i<=n;i++)
{
found[i]=(found[i-]+a[i])%(1LL<<(mp+));
order[i]=found[i];
}
sort(order,order+n+);
cnt=unique(order,order+n+)-order-;
int ans=;
for(int i=;i<=n;i++)
{
p=lower_bound(order,order+cnt+,found[i])-order;
if(order[p]!=found[i]) p--;
p++;
add(p,);
ans^=sum(p);
p=lower_bound(order,order+cnt+,found[i]-(1LL<<mp))-order;
if(order[p]!=found[i]-(1LL<<mp)) p--;
p++;
ans^=sum(p);
p=lower_bound(order,order+cnt+,found[i]+(1LL<<mp))-order;
if(p==cnt+ || order[p]!=found[i]+(1LL<<mp)) p--;
p++;
ans^=sum(p);
}
if(ans) ans2|=(1LL<<mp);
return ;
}
int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++)
scanf("%lld",&a[i]);
ans1=ans2=;
for(int i=;i<=;i++) qy1(i);
for(int i=;i<=;i++) qy2(i);
printf("%lld %lld\n",ans1,ans2);
return ;
}

bzoj 4017: 小Q的无敌异或的更多相关文章

  1. BZOJ 4017 小 Q 的无敌异或 ( 树状数组、区间异或和、区间异或和之和、按位计贡献思想 )

    题目链接 题意 : 中文题 分析 : 首先引入两篇写的很好的题解 题解一.题解二 听说这种和异或相关区间求和的问题都尽量按位考虑 首先第一问.按二进制位计贡献的话.那么对于第 k 位而言 其贡献 = ...

  2. BZOJ4017 小Q的无敌异或(位运算)

    题目链接 小Q的无敌异或 好久之前做的这道题了……参照了别人的博客……还是没有全懂. 第一个问题维护个前缀就好了,第二个问题还要用树状数组维护…… #include <bits/stdc++.h ...

  3. bzoj 4815 小Q的表格 —— 反演+分块

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4815 思路就和这里一样:https://blog.csdn.net/leolyun/arti ...

  4. BZOJ [Cqoi2017] 小Q的棋盘

    题解:枚举最后在哪里停止,然后剩下的步数/2 也就是找最大深度 枚举终止位置算是一种思路吧 #include<iostream> #include<cstdio> #inclu ...

  5. bzoj 4813: [Cqoi2017]小Q的棋盘

    Description 小Q正在设计一种棋类游戏.在小Q设计的游戏中,棋子可以放在棋盘上的格点中.某些格点之间有连线,棋子只能 在有连线的格点之间移动.整个棋盘上共有V个格点,编号为0,1,2-,V- ...

  6. bzoj 4813: [Cqoi2017]小Q的棋盘 [树形背包dp]

    4813: [Cqoi2017]小Q的棋盘 题意: 某poj弱化版?树形背包 据说还可以贪心... #include <iostream> #include <cstdio> ...

  7. bzoj 4815: [Cqoi2017]小Q的表格 [数论]

    4815: [Cqoi2017]小Q的表格 题意: 单点修改,查询前缀正方形和.修改后要求满足条件f(a,b)=f(b,a), b×f(a,a+b)=(a+b)*f(a,b) 一开始sb了认为一次只会 ...

  8. 【BZOJ 5125】小Q的书架

    Problem Description 小 \(Q\) 有 \(n\) 本书,每本书有一个独一无二的编号,现在它们正零乱地在地上排成了一排. 小 \(Q\) 希望把这一排书分成恰好 \(k\) 段,使 ...

  9. 腾讯笔试题:小Q硬币组合

    腾讯有一道机试题: 大概意思是: 小Q非常富有,拥有非常多的硬币,小Q的拥有的硬币是有规律的,对于所有的非负整数K,小Q恰好> 各有两个数值为2^k,的硬币,所以小Q拥有的硬币是1,1,2,2, ...

随机推荐

  1. python初步学习-python数据类型之strings(字符串)

    数据类型-字符串 字符串是 Python 中最常用的数据类型.我们可以使用引号(''或者"")来创建字符串 var1 = 'Hello World!' var2 = "P ...

  2. bzoj 3028 母函数

    首先我们可以求出来所有食物的母函数: 汉堡:f(x)=1/(1-x^2). 可乐:f(x)=1+x. 鸡腿:f(x)=1+x+x^2. 蜜桃多:f(x)=x/(1-x^2). 鸡块:f(x)=1/(1 ...

  3. JqGrid自定义(图片)列

    $("#gridTable").jqGrid({ //...其它属性 colModel: [ //...其它列 { name: , align: "center" ...

  4. vue实现微信对话

    因为项目中需要实现仿微信对话功能,于是抽空实现了下,主要是h5的canvas的把图片和文字绘制到画布上 原文来自我的个人博客:http://lvhww.com/index.php/archives/6 ...

  5. 创建Fragment和传递数值

    下面在扩展一下创建Fragment和传递数值 如果我们不需要传递数值,那就直接可以在宿主activity中,跟平常一样创建fragment,但是如果我们需要传递数据的话,可以使用newInstance ...

  6. 双内网渗透代理之reGeorg+Proxifier

    由于这个工具第一次体验感觉还不错,很稳定.因此在这记录一下reGeorg+Proxifier的配置及其使用. 下载地址 :https://github.com/sensepost/reGeorg.gi ...

  7. 安全测试===Web 安全渗透方面的学习路线

    作者:向生李链接:https://www.zhihu.com/question/21914899/answer/39344435来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明 ...

  8. sicily 1052. Candy Sharing Game

    Constraints Time Limit: 1 secs, Memory Limit: 32 MB Description A number of students sit in a circle ...

  9. C基础 工程中常用的排序

    引言 - 从最简单的插入排序开始 很久很久以前, 也许都曾学过那些常用的排序算法. 那时候觉得计算机算法还是有点像数学. 可是脑海里常思考同类问题, 那有什么用呢(屌丝实践派对装逼学院派的深情鄙视). ...

  10. Unknown character set: 'utf8mb4'

    出现Unknown character set: 'utf8mb4'该错误是因为你的mysql-connector-java版本太高了,现在的mysql编码方式utf8mb4  然而老版本的却是utf ...