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(活用树状数组)的更多相关文章

  1. UVA_11525 树状数组的活用 二分

    我们知道1——k有K!种排列,现在给定k和n,要你按字典序输出 第n种排列的数列 而且题目给的 n是 n=S1(k-1)!+S2(k-2)!+...+Sk-1*1!+Sk*0!(0=<Si< ...

  2. BZOJ-5055-膜法师(离散化+树状数组)

    Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然,他能为长者所续的时间,为这三个维度上能量的乘 ...

  3. BZOJ_5055_膜法师_树状数组+离散化

    BZOJ_5055_膜法师_树状数组+离散化 Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然 ...

  4. bzoj 5055: 膜法师——树状数组

    Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇宙的膜法师,想偷取其中的三个维度为伟大的长者续秒, 显然,他能为长者所续的时间,为这三个维度上能量的乘 ...

  5. bzoj 5055: 膜法师 -- 树状数组

    5055: 膜法师 Time Limit: 10 Sec  Memory Limit: 128 MB Description 在经历过1e9次大型战争后的宇宙中现在还剩下n个完美维度, 现在来自多元宇 ...

  6. 小结:线段树 & 主席树 & 树状数组

    概要: 就是用来维护区间信息,然后各种秀智商游戏. 技巧及注意: 一定要注意标记的下放的顺序及影响!考虑是否有叠加或相互影响的可能! 和平衡树相同,在操作每一个节点时,必须保证祖先的tag已经完全下放 ...

  7. HDU 4970 Killing Monsters(树状数组)

    Killing Monsters Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other ...

  8. 【bzoj5055】膜法师 离散化+树状数组

    题目描述 给定一个序列$a$,求满足$i<j<k$且$a_i<a_j<a_k$的三元组$(i,j,k)$的个数. 输入 第一行1个数 n 第二行n个数 a_i 输出 一个数,表 ...

  9. P3760-[TJOI2017]异或和【树状数组】

    正题 题目链接:https://www.luogu.com.cn/problem/P3760 题目大意 给出\(n\)个数字的一个序列\(a\),求它所有区间和的异或和 \(n\leq 10^5,\s ...

随机推荐

  1. nrm是什么?以及nrm的安装与命令

    nrm的作用与安装使用 一.nrm是什么? 这是官方的原话: 开发的npm registry 管理工具 nrm, 能够查看和切换当前使用的registry, 最近NPM经常 down 掉, 这个还是很 ...

  2. R语言与分类算法的绩效评估(转)

    关于分类算法我们之前也讨论过了KNN.决策树.naivebayes.SVM.ANN.logistic回归.关于这么多的分类算法,我们自然需要考虑谁的表现更加的优秀. 既然要对分类算法进行评价,那么我们 ...

  3. Mysql数据库二进制安装

    MySQL数据库有四种安装方法: 源码包编译安装 RPM包安装 二进制文件安装 官方yum源安装 这里我们主要介绍二进制包的安装方法 在MySQL官网下载二进制包并且上传到服务器上 解压二进制包 [r ...

  4. 一步一步实现基于GPU的pathtracer(一):基础

    出于3D计算机图形学和图形渲染方面的个人兴趣,脑子里便萌生出了自己实现一个渲染器的想法,主要是借助pathtracing这种简单的算法,外加GPU加速来实现,同时也希望感兴趣的朋友们能够喜欢,也欢迎提 ...

  5. 【JAVAEE学习笔记】hibernate04:查询种类、HQL、Criteria、查询优化和练习为客户列表增加查询条件

    一.查询种类 1.oid查询-get 2.对象属性导航查询 3.HQL 4.Criteria 5.原生SQL 二.查询-HQL语法 //学习HQL语法 public class Demo { //基本 ...

  6. 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率

    隐马尔科夫模型HMM(一)HMM模型 隐马尔科夫模型HMM(二)前向后向算法评估观察序列概率 隐马尔科夫模型HMM(三)鲍姆-韦尔奇算法求解HMM参数(TODO) 隐马尔科夫模型HMM(四)维特比算法 ...

  7. Web前端性能优化全攻略

    网页制作poluoluo文章简介:Web 前端性能优化是个大话题,是个值得运维人员持续跟踪的话题,是被很多网站无情忽视的技术. Web 前端性能优化是个大话题,是个值得运维人员持续跟踪的话题,是被很多 ...

  8. [Leetcode] Binary search, Divide and conquer--240. Search a 2D Matrix II

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  9. 高防TTCDN

    TCDN是深圳市云中漫网络科技公司高防CDN产品的品牌名称,既可以防御,也可以达到加速的效果,价格实惠.TTCDN适用于WEB应用,可以隐藏源站服务器IP,有效的减轻源站服务器压力,加快全国各地区线路 ...

  10. JS实现AOP拦截方法调用

    //JS实现AOP拦截方法调用function jsAOP(obj,handlers) {    if(typeof obj == 'function'){        obj = obj.prot ...