题目链接

BZOJ4888

题解

要求所有连续异或和,转化为任意两个前缀和相减

要求最后的异或和,转化为求每一位\(1\)的出现次数

所以我们只需要对每一个\(i\)快速求出\(sum[i] - sum[j] \quad [j < i]\)当前位的\(1\)的个数

显然是将前\(i\)个数放到某一个数据结构中查询

我的思路到这里停住

两个数相减,要第\(b\)位为\(1\),我们放到具体情境中观察:

假若\(sum[i]\)的第\(b\)位为\(1\)

....1....

....?....

1、如果\(?=0\)

就是

....1....

....0....

发现\(1\)后面的数大于等于 \(0\)后面的数,为此时相减后该位为\(1\)的充要条件

2、如果\(?=1\)

就是

....1....

....1....

发现\(sum[i]\)的\(1\)后面的数小于\(sum[j]\)的\(1\)后面的数,为此时相减后该位为\(1\)的充要条件

如果第\(b\)位为\(0\)也是类似的讨论

如果我们将该位为\(0\)和\(1\)的数分开讨论,现在问题就转化为了,如何快速求当前某一范围内的数的个数

显然就是对\(0\)和\(1\)分别开一个权值树状数组啦

题目中\(a[i]\)之和\(\le 10^6\)的条件也是一个明显的暗示

这样我们就用\(O(log_2(max\{a_i\}) * nlog\sum a_i) \approx O(nlog^2n)\)的时间复杂度做出这道题了

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#define Redge(u) for (int k = h[u],to; k; k = ed[k].nxt)
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define mp(a,b) make_pair<int,int>(a,b)
#define cls(s) memset(s,0,sizeof(s))
#define cp pair<int,int>
#define LL long long int
#define lbt(x) (x & -x)
using namespace std;
const int maxn = 100005,maxm = 1000005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
int MX = 1000001;
struct BIT{
int s[maxm];
void clear(){cls(s);}
void add(int u){while (u <= MX) s[u]++,u += lbt(u);}
int query(int u){int re = 0; while (u) re += s[u],u -= lbt(u); return re;}
int sum(int l,int r){return query(r) - query(l - 1);}
}T0,T1;
int n,a[maxn],mx;
bool check(int b){
T0.clear(); T1.clear();
LL cnt = 0; int tmp;
for (int i = 0; i <= n; i++){
tmp = a[i] % b + 1;
if (a[i] & b){
cnt += T0.sum(1,tmp) + T1.sum(tmp + 1,MX);
T1.add(tmp);
}
else {
cnt += T0.sum(tmp + 1,MX) + T1.sum(1,tmp);
T0.add(tmp);
}
}
return cnt & 1;
}
int main(){
n = read(); int x,ans = 0;
REP(i,n) a[i] = a[i - 1] + (x = read()),mx = max(mx,a[i]);
for (int i = 0; mx; i++,mx >>= 1){
if (check(1 << i)) ans += (1 << i);
}
printf("%d\n",ans);
return 0;
}

BZOJ4888 [Tjoi2017]异或和 【树状数组】的更多相关文章

  1. [BZOJ4888][TJOI2017]异或和(树状数组)

    题目描述 在加里敦中学的小明最近爱上了数学竞赛,很多数学竞赛的题都是与序列的连续和相关的.所以对于一个序列,求出它们所有的连续和来说,小明觉得十分的简单.但今天小明遇到了一个序列和的难题,这个题目不仅 ...

  2. BZOJ.4888.[TJOI2017]异或和(树状数组)

    BZOJ 洛谷 \(Description\) 求所有区间和的异或和. \(n\leq 10^5,\ \sum a_i\leq 10^6\). \(Solution\) 这样的题还是要先考虑按位做. ...

  3. Luogu3760 TJOI2017 异或和 树状数组

    传送门 题意:给出一个长度为$N$的非负整数序列,求其中所有连续区间的区间和的异或值.$N \leq 10^5$,所有元素之和$\leq 10^6$ 设序列的前缀和为$s_i$,特殊地,$s_0=0$ ...

  4. 【Foreign】异色弧 [树状数组]

    异色弧 Time Limit: 20 Sec  Memory Limit: 256 MB Description Input Output 仅一行一个整数表示答案. Sample Input 8 1 ...

  5. P5057 [CQOI2006]简单题 前缀异或差分/树状数组

    好思路,好思路... 思路:前缀异或差分 提交:1次 题解:区间修改,单点查询,树状数组,如思路$qwq$ #include<cstdio> #include<iostream> ...

  6. 洛谷 P6225 [eJOI2019]异或橙子 (树状数组)

    题意:有\(n\)个数,起始值均为\(0\),进行\(q\)次操作,每次输入三个数,如果第一个数为\(1\),则将第\(i\)个数修改为\(j\),如果为\(2\),则求区间\([l,r]\)内的所有 ...

  7. [CSP-S模拟测试]:异或(树状数组+LCA)

    题目传送门(内部题21) 输入格式 第一行一个字符串$str$,表示数据类型.第二行一个正整数$k$,表示集合$K$的大小,保证$k>1$.接下来$k$行每行$k$个数,第$i$行第$j$个数表 ...

  8. 【BZOJ4888】[TJOI2017]异或和(树状数组)

    [BZOJ4888][TJOI2017]异或和(树状数组) 题面 BZOJ 洛谷 题解 考虑每个位置上的答案,分类讨论这一位是否存在一,值域树状数组维护即可. #include<iostream ...

  9. BZOJ4888 [Tjoi2017]异或和 FFT或树状数组+二进制拆位

    题面 戳这里 简要题解 做法一 因为所有数的和才100w,所以我们可以直接求出所有区间和. 直接把前缀和存到一个权值数组,再倒着存一遍,大力卷积一波. 这样做在bzoj目前还过不了,但是luogu开O ...

随机推荐

  1. LeetCode94. Binary Tree Inorder Traversal

    题目 给定一个二叉树,返回它的中序 遍历. 示例: 输入: [1,null,2,3] 1 \ 2 / 3 输出: [1,3,2] 进阶: 递归算法很简单,你可以通过迭代算法完成吗? 考点 stack ...

  2. elasticsearch-dsl聚合-2

    接续上篇,本篇介绍elasticsearch聚合查询,使用python库elasticsearch-dsl进行聚合查询操作. 条形图 聚合有一个令人激动的特性就是能够十分容易地将数据转换成图表和图形. ...

  3. 利用sysbench进行MySQL OLTP基准测试

      Preface       In order to know clearly about the real performance threshold of database server,we ...

  4. 安装破解IDEA(个人使用)

    安装的过程,许多的教程都会有,我在这里附上一两个链接吧:https://blog.csdn.net/newabcc/article/details/80601933 他这里也有破解过程,但是比较麻烦, ...

  5. 统计重复IP并排序

    #降序排列 sort ip20180623.log | uniq -c | sort -rn | more #可以输出到文件哦 sort ip20180623.log | uniq -c | sort ...

  6. 使用windows api安装windows服务程序(C#)

    3个步骤: 1.安装器代码编写 2.安装器工具类编写 1)安装.启动服务) 2)卸载服务 3.windows服务程序编写(参考:多线程.方便扩展的Windows服务程序框架) 4.代码下载,在文末(注 ...

  7. PHP开发搭建环境二:开发工具PhpStorm安装、激活以及配置

    关于php的开发工具很多,目前市面上最好用最强大的莫过于PhpStorm这款开发神器了,但是鉴于很多开发者朋友在网站上下载的PhpStorm开发工具不能用,或者使用起来很不方便,笔者把最好用的下载地址 ...

  8. python之获取微信好友列表并保存文档中

    代码如下 from wxpy import * from pprint import pprint #登录微信 bot = Bot() my_friend = bot.friends() f = op ...

  9. P1338 末日的传说 逆序数对

    题目描述 只要是参加jsoi活动的同学一定都听说过Hanoi塔的传说:三根柱子上的金片每天被移动一次,当所有的金片都被移完之后,世界末日也就随之降临了. 在古老东方的幻想乡,人们都采用一种奇特的方式记 ...

  10. [BZOJ3172 ][Tjoi2013]单词(AC自动机)

    Description 不稳定的传送门 某人读论文,一篇论文是由许多单词组成.但他发现一个单词会在论文中出现很多次,现在想知道每个单词分别在论文中出现多少次.单词个数<=200,单词总长度< ...