TOJ4114(活用树状数组)
TOJ指天津大学onlinejudge
题意:给你由N个数组成的数列,算出它们的所有连续和的异或和,比如:数列{1,2},则answer = 1 ^ 2 ^ (1 + 2) = 0。
这道题有几个关键点:
1.这道题要将十进制数换成二进制数,并且对这些二进制数按位计算,比如说上面的式子,我们将它列成竖式:
01
10
11
可以发现,对于第一位来说,一共有2个1,是偶数,异或值为0。answer += 0 * (1<<0)。对于第二位来说,一共有2个1,异或值为0,answer += 0 * (1<<1)。最终answer = 0;
2.Sum(i~j) = S[j] - S[i - 1]。 (S[0] = 0) 所以我们算式可以看成(S[1] - S[0]) ^ (S[2] - S[1]) ^ (S[2] - S[0]) ^ (S[3] - S[0]) ^ (S[3] - S[1]) ^ (S[3] - S[2]) ^ ..........
所以我们可以按块来看这些算式中的项,每一块就S[i]与S[i - 1]......S[0]做差得到的。
综上,我们计算异或和时,我们只需要预处理一下,算出每一个S[i],然后从头到尾扫n次,每一次计算出这些二进制数某一位一共有多少个1(就像上面所举例子一样),看看是偶数还是奇数,
如果是奇数,就answer += 1 * (1<<i)。
现在来说扫描时候的具体操作,假设我们现在已经计算完了S[1]....S[i]这些组成异或和的各项在某一位k的1的个数,在扫到S[i + 1]时,相当于又多了(S[i +1] - S[0]) ^ .......^ (S[i + 1] - S[i])这 i 项来统计,
我就只需要计算出S[i + 1]与前面各项S[ j ] (j属于[ 0 , i ]) 的差在这一位产生了多少个1,对于S[i + 1]与某一个S[ j ]来说,这取决于S[i + 1]和S[ j ]在这一位的值和S[i + 1]与S[ j ]在更低诸位上的大小关系。
在这里,我将S[i + 1]在这一位的值记为A1,更低的诸位统一记为B1,S[ j ]在这一位的值记为A2,更低诸位的统一记为B2。
1.当A1 == 1时,有两种情况可以产出一个1:
情况Ⅰ:A2 == 0,且B1 >= B2。
情况Ⅱ:A2 == 1,且B1 < B2(可以从前面借位来产生1,就像10 - 9 = 1这样)
2.当A1 == 0时,有两种情况可以产出一个1:
情况Ⅰ:A2 == 0,且B1< B2
情况Ⅱ:A2 == 1,且B1 >= B2。
由此可以看出,对于S[i + 1]与前面诸前缀和之差在某一位能产生多少个1,我只要知道S[ j ]比这一位低的诸位与S[i + 1]比这一位低的诸位之大小关系即可。
这个可以用树状数组来保存,树状数组的下标表示的是值域,BIT[ Bi ]中存的比这一位低的诸位B小于等于Bi的S[ k ]的个数,由于我们扫这一遍S[ i ]的目的就是为了计算特定的一位,
所以我们有多少位就扫多少次,扫完一次就清空一次树状数组。由于还跟S[ j ]在这一位的值有关,所以我们开两个树状数组,一个记录在这一位为1的S[i],一个则记录在这一位为0的S[j]。
对于每一个S[i]我们边算边存,如果S[i]在这一位为1,则存在BIT_1中;如果为0,则存在BIT_0中。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#define maxn 100005
#define maxn2 1000005
using namespace std;
int BIT_0[maxn2],BIT_1[maxn2];
int S[maxn];
int lowbit(int k)
{
return (k & (-k));
}
void add(int v,int pos,int mmax,int a[])
{
while(pos <= mmax){
a[pos] += v;
pos += lowbit(pos);
}
}
int sum(int pos,int a[])
{
int ret = ;
while(pos > ){
ret += a[pos];
pos -= lowbit(pos);
}
return ret;
}
int main()
{
int T;
scanf("%d",&T);
while(T--){
memset(S,,sizeof(S));
int n;
scanf("%d",&n);
for(int i = ;i <= n;++i){
scanf("%d",&S[i]);
S[i] += S[i - ];
}
int temp = S[n];
int len = ;
while(temp > ){
temp = temp>>;
++len;
}
int answer = ;
for(int i = ;i < len;++i){
int cnt = ;
int cnt_0 = ,cnt_1 = ,mmax = (<<i);
for(int j = ;j <= n;++j){
int tail = S[j] % (<<i);
++tail;
int t_cnt = ;
if(S[j] & (<<i)){
t_cnt += sum(tail,BIT_0);
t_cnt += (cnt_1 - sum(tail,BIT_1));
add(,tail,mmax,BIT_1);
++cnt_1;
}
else{
t_cnt += sum(tail,BIT_1);
t_cnt += (cnt_0 - sum(tail,BIT_0));
add(,tail,mmax,BIT_0);
++cnt_0;
}
cnt += t_cnt;
}
if(cnt & ) answer += (<<i);
memset(BIT_0,,sizeof(BIT_0));
memset(BIT_1,,sizeof(BIT_1));
}
printf("%d\n",answer);
}
return ;
}
这里有一个小技巧,由于lowbit( )不好处理0,所以我把每一个tail都加1,(tail的取值最小就是0),这样sum(x)其实算的是tail在[0,x-1]之间的S[j]
本题启发:树状数组的下标用来表示值域
TOJ4114(活用树状数组)的更多相关文章
- UVA_11525 树状数组的活用 二分
我们知道1——k有K!种排列,现在给定k和n,要你按字典序输出 第n种排列的数列 而且题目给的 n是 n=S1(k-1)!+S2(k-2)!+...+Sk-1*1!+Sk*0!(0=<Si< ...
- BZOJ-5055-膜法师(离散化+树状数组)
Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然,他能为长者所续的时间,为这三个维度上能量的乘 ...
- BZOJ_5055_膜法师_树状数组+离散化
BZOJ_5055_膜法师_树状数组+离散化 Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然 ...
- bzoj 5055: 膜法师——树状数组
Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然,他能为长者所续的时间,为这三个维度上能量的乘 ...
- bzoj 5055: 膜法师 -- 树状数组
5055: 膜法师 Time Limit: 10 Sec Memory Limit: 128 MB Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇 ...
- 小结:线段树 & 主席树 & 树状数组
概要: 就是用来维护区间信息,然后各种秀智商游戏. 技巧及注意: 一定要注意标记的下放的顺序及影响!考虑是否有叠加或相互影响的可能! 和平衡树相同,在操作每一个节点时,必须保证祖先的tag已经完全下放 ...
- HDU 4970 Killing Monsters(树状数组)
Killing Monsters Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Other ...
- 【bzoj5055】膜法师 离散化+树状数组
题目描述 给定一个序列$a$,求满足$i<j<k$且$a_i<a_j<a_k$的三元组$(i,j,k)$的个数. 输入 第一行1个数 n 第二行n个数 a_i 输出 一个数,表 ...
- P3760-[TJOI2017]异或和【树状数组】
正题 题目链接:https://www.luogu.com.cn/problem/P3760 题目大意 给出\(n\)个数字的一个序列\(a\),求它所有区间和的异或和 \(n\leq 10^5,\s ...
随机推荐
- 关于SESSION失效和关闭浏览器问题
关闭浏览器和session失效没有任何关系, session本身有一个存活时间,在tomcat中默认的是30分钟, 这也就是楼上说的不是马上失效 但和浏览器不要划等号 因为即使你浏览器一直开着,如 ...
- Spring-bean作用域scope详解
Spring Framework支持五种作用域(其中有三种只能用在基于web的Spring ApplicationContext). singleton 在每个Spring IoC容器中一个bean定 ...
- javaWeb学习总结(1)- JavaWeb开发入门
一.基本概念 1.1.WEB开发的相关知识 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源. Internet上供外界访问的Web资源分为: 静态web资源( ...
- Java反射机制剖析(二)-功能以及举例
从<java反射机制剖析(一)>的API我们看到了许多接口和类,我们能够通过这些接口做些什么呢? 从上篇API中我们能看到它能够完成下面的这些功能: 1) 获得类 A. 运 ...
- OpenCV探索之路(十五):角点检测
角点检测是计算机视觉系统中用来获取图像特征的一种方法.我们都常说,这幅图像很有特点,但是一问他到底有哪些特点,或者这幅图有哪些特征可以让你一下子就识别出该物体,你可能就说不出来了.其实说图像的特征,你 ...
- 【java8】慎用java8的foreach循环
虽然java8出来很久了,但是之前用的一直也不多,最近正好学习了java8,推荐一本书还是不错的<写给大忙人看的javase8>.因为学习了Java8,所以只要能用到的地方都会去用,尤其是 ...
- [asp.net mvc 奇淫巧技] 04 - 你真的会用Action的模型绑定吗?
在QQ群或者一些程序的交流平台,经常会有人问:我怎么传一个数组在Action中接收.我传的数组为什么Action的model中接收不到.或者我在ajax的data中设置了一些数组,为什么后台还是接收不 ...
- 封装TableView有可能用到的数据结构和UITableViewCell的一个继承类
最近4年的时间,我已经做了5个App完全独立开发, 工作经历5个App, 维护了两个App. 在这期间用的最多的是UITableView, 因此也有许多感觉可以封装的. 现在就是我封装的. RXCel ...
- jquery中的$(document).ready()使用小结
本篇文章主要是对jquery中的$(document).ready()使用方法进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助 window.onload = function(){ ...
- 关于dedecms的操作
系统基本参数的配置 如图 上面是设置系统的基本参数 操作是进入系统后台>点击系统>点击系统基本参数 然后右边就是系统参数等等基本参数了 记住修改后要点击确定哟 ☺ 数据库备份 如图: ...