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. 【vijos】P1083 小白逛公园

    [算法]线段树 [题解] 学自:https://vijos.org/p/1083/solution(wang_yanheng的回答) 回溯时维护一段区间的以下域: sumL:从左端点起连续区间的最大和 ...

  2. UIPikerView的属性---iOS-Apple苹果官方文档翻译

    本系列所有开发文档翻译链接地址:iOS7开发-Apple苹果iPhone开发Xcode官方文档翻译PDF下载地址  //转载请注明出处--本文永久链接:http://www.cnblogs.com/C ...

  3. 【CF558E】 A Simple Task (权值线段树)

    题目链接 用权值线段树维护每个字母在\([l,r]\)出现的次数,每次修改把每个字母在区间的出现次数记下来,然后清空这段区间,再按顺序插进去就好了. 时间复杂度\(O(n\log n*26)\) (好 ...

  4. javascript中的addEventListener与attchEvent

    1.addEventListener 该方法用于向指定元素添加事件句柄 浏览器的支持情况为chrome1.0.ie9+.fireFox1.0.opera7.0 该方法包含三个参数event, func ...

  5. Python自动化运维 - Django(三)CSRF - Cookie&Session

    CSRF跨站请求伪造 CSRF跨站点请求伪造(Cross—Site Request Forgery),跟XSS攻击一样,存在巨大的危害性,你可以这样来理解:攻击者盗用了你的身份,以你的名义发送恶意请求 ...

  6. python自动开发之第二十五天

    一.组合搜索 参考: http://www.cnblogs.com/ccorz/p/5985205.html 二.JSONP 1.在同源策略下,在某个服务器下的页面是无法获取到该服务器以外的数据的,但 ...

  7. C++学习之路(六):实现一个String类

    直接贴代码吧,这段时间准备面试也正好练习了一下. class String { public: String(const char *str = ""); ~String(void ...

  8. C基础入门 - 第一章 - C语言绪言

    第1章 C语言绪言 1.1 C语言概述 1.1.1 C语言世界 1.1.2 C语言学习, 能当饭吃吗 1.2 开发环境构建 1.2.1 visual studio安装使用 1.2.2 visual s ...

  9. OC 07 类的扩展

    1.NSDate的使用 NSDate是Cocoa中⽤于处理⽇期和时间的基础类,封装了某⼀给定的时刻(含日期,时间,时区) 注意NSLog(@“%@”,nowDate);⽆论你是哪个时区的时间,打印时总 ...

  10. 【LabVIEW技巧】工厂模式_简单工厂

    前言 上一个文章介绍了如何学习LabVIEW OOP,简要的提及了一些OOP学习中注意的事项,许多文章的读者反映写的太范,后文会逐步缩小范围,讨论在LabVIEW中各个模式的应用. 工厂模式概述 工厂 ...