题目链接

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;
}

最新文章

  1. EmberJs之数组绑定@each&amp;[]
  2. [转]virtualenv and virtualenvwrapper
  3. Intent.putExtra()传递Object对象或者ArrayList&lt;Object&gt; (转)
  4. MATLAB与C/C++混合编程的一些总结
  5. 程序员是怎么炼成的---OC题集--练习答案与题目(3)
  6. 获得SQLSERVER的表字段等架构信息
  7. 2016021901 - ubuntu截图技巧
  8. linux删除、移动、拷贝时,加-f仍然会提示的解决办法
  9. day2_python学习笔记_chapter4_标准类型和内建函数
  10. ubuntu下ftp服务
  11. Tree POJ - 1741【树分治】【一句话说清思路】
  12. react初入门
  13. Vue通过id跳转到商品详情页
  14. element ui里dialog关闭后清除验证条件
  15. Kerberos 互信免登陆
  16. http://ctf.bugku.com/challenges#%E6%B8%B8%E6%88%8F%E8%BF%87%E5%85%B3--游戏过关
  17. c#: PointToClient与PointToScreen
  18. 可视化 linux 无法启动eclipse 报错No java virtual machine
  19. 编写高性能的jQuery代码
  20. java 当读取的结果为-1时候说明已经读取结束了

热门文章

  1. html5 canvas中CanvasGradient对象用法
  2. 【模板时间】◆模板&#183;III◆ 单调子序列
  3. python格式化输出的方式汇总
  4. 交换机基础配置之跨交换机划分vlan
  5. 前端调试vConsole
  6. Flask初学者:蓝图Blueprint
  7. ZOJ3640 概率DP
  8. C# 控件置于最顶层、最底层、隐藏、显示
  9. 使用dataframe解决spark TopN问题:分组、排序、取TopN和join相关问题
  10. 2,Flask 中的 Render Redirect HttpResponse