BZOJ4888 [Tjoi2017]异或和 【树状数组】
题目链接
题解
要求所有连续异或和,转化为任意两个前缀和相减
要求最后的异或和,转化为求每一位\(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]异或和 【树状数组】的更多相关文章
- [BZOJ4888][TJOI2017]异或和(树状数组)
题目描述 在加里敦中学的小明最近爱上了数学竞赛,很多数学竞赛的题都是与序列的连续和相关的.所以对于一个序列,求出它们所有的连续和来说,小明觉得十分的简单.但今天小明遇到了一个序列和的难题,这个题目不仅 ...
- BZOJ.4888.[TJOI2017]异或和(树状数组)
BZOJ 洛谷 \(Description\) 求所有区间和的异或和. \(n\leq 10^5,\ \sum a_i\leq 10^6\). \(Solution\) 这样的题还是要先考虑按位做. ...
- Luogu3760 TJOI2017 异或和 树状数组
传送门 题意:给出一个长度为$N$的非负整数序列,求其中所有连续区间的区间和的异或值.$N \leq 10^5$,所有元素之和$\leq 10^6$ 设序列的前缀和为$s_i$,特殊地,$s_0=0$ ...
- 【Foreign】异色弧 [树状数组]
异色弧 Time Limit: 20 Sec Memory Limit: 256 MB Description Input Output 仅一行一个整数表示答案. Sample Input 8 1 ...
- P5057 [CQOI2006]简单题 前缀异或差分/树状数组
好思路,好思路... 思路:前缀异或差分 提交:1次 题解:区间修改,单点查询,树状数组,如思路$qwq$ #include<cstdio> #include<iostream> ...
- 洛谷 P6225 [eJOI2019]异或橙子 (树状数组)
题意:有\(n\)个数,起始值均为\(0\),进行\(q\)次操作,每次输入三个数,如果第一个数为\(1\),则将第\(i\)个数修改为\(j\),如果为\(2\),则求区间\([l,r]\)内的所有 ...
- [CSP-S模拟测试]:异或(树状数组+LCA)
题目传送门(内部题21) 输入格式 第一行一个字符串$str$,表示数据类型.第二行一个正整数$k$,表示集合$K$的大小,保证$k>1$.接下来$k$行每行$k$个数,第$i$行第$j$个数表 ...
- 【BZOJ4888】[TJOI2017]异或和(树状数组)
[BZOJ4888][TJOI2017]异或和(树状数组) 题面 BZOJ 洛谷 题解 考虑每个位置上的答案,分类讨论这一位是否存在一,值域树状数组维护即可. #include<iostream ...
- BZOJ4888 [Tjoi2017]异或和 FFT或树状数组+二进制拆位
题面 戳这里 简要题解 做法一 因为所有数的和才100w,所以我们可以直接求出所有区间和. 直接把前缀和存到一个权值数组,再倒着存一遍,大力卷积一波. 这样做在bzoj目前还过不了,但是luogu开O ...
随机推荐
- python实现排序之冒泡排序
冒泡排序:是将一串无需的数字,排列成有序的.通过相邻的两个数作比较,大的往后移,经过反复的比较,最后得出一串有序的数列. 那么用代码该如何实现? 其实这个问题的思路就是判断每相邻的两个数,进行大小比较 ...
- laravel查看执行的sql语句
方法一: 我们有时候想测试一段代码生产的 SQL 语句,比如: 我们想看 App\User::all(); 产生的 SQL 语句,我们简单在 routes.php 做个实验即可: //app/Http ...
- 易语言制作的QQ聊天中常用的GIF图片【带源码下载】
该软件调用网页实现表情包制作,使用了精益模块. 最近比较火的王境泽.张学友.切格瓦拉.为所欲为.今天星期五.黑人问号脸.偷电瓶车.诸葛孔明.金坷垃等都可以通过此软件在线制作属于你的表情包. 太困了懒得 ...
- 进程、线程、协程和GIL(二)
上一篇博客讲了进程.线程.协程和GIL的基本概念,这篇我们来说说在以下三点: 1> python中使用threading库来创建线程的两种方式 2> 使用Event对消来判断线程是否已启动 ...
- strak组件(6):列表定制列应用和引入静态文件
效果图: 新增函数 def get_choice_text(title, field) 闭包函数,显示choice字段 def inner(self, obj=None, is_header=None ...
- POJ:3259-Wormholes(最短路判断负环)
Wormholes Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 58153 Accepted: 21747 Descripti ...
- Highest Tower 18中南多校第一场H题
一.题意 给出N个方块,要求给出一个方案,使得1. 所有方块都被使用到(题目数据保证这点) 2.所有方块垒成一个塔,且上面的方块宽度小于下面的方块 3.每个方块只能用一次,可以横着或者竖着. n范围5 ...
- python time时间模块
在Python中,通常有这三种方式来表示时间:时间戳.元组(struct_time).格式化的时间字符串 (1)时间戳(timestamp) :通常来说,时间戳表示的是从1970年1月1日00:00: ...
- JAVA中使用AES加密解密
技术交流群: 233513714 /** * AES加密测试 * * @param str 加密参数 */ public void aesTest(String str) { log.info(&qu ...
- BitLocker:如何启用网络解锁
TechNet 库Windows ServerWindows Server 2012 R2 和 Windows Server 2012服务器角色和技术安全和保护BitLockerBitLocker 中 ...