E. Beautiful Subarrays 字典树
http://codeforces.com/contest/665/problem/E
给定一个序列,问其中有多少个区间,所有数字异或起来 >= k
看到异或,就应该想到异或的性质,A^B^B = A,所以,用sum[i]表示1--i的异或值,那么i...j的异或值就是sum[j] ^ sum[i - 1]
所以原问题转化为在一个数组中,任选两个数,异或值 >= k
首先所有数字 <= 1e9
那么前缀异或值 <= 2^31 - 1
那么用int就够了,从30位开始插入字典树,(1 << 31)是溢出的
查找的时候,分两类
1、当前的位置中k的二进制位是0,就是第15位,如果k的二进制位是0,那么往反方向走字典树的子树总是可以得,这个时候只需要加上去子树大小即可。
2、如果那一位k是1,我们没法马上判断贡献,那么只能往反方向贪心走字典树。
注意的就是叶子节点有可能没走到,需要最后加上来。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 1e6 + ;
const int N = ;
int a[maxn];
int sum[maxn];
int n, k;
struct node {
struct node *pNext[N];
int cnt;
}tree[maxn * ];
int t;
struct node * create() {
struct node *p = &tree[t++];
for (int i = ; i < N; ++i) {
p->pNext[i] = ;
}
p->cnt = ;
return p;
}
void insert(struct node **T, int val) {
struct node *p = *T;
if (p == NULL) {
p = *T = create();
}
for (int i = ; i >= ; --i) {
int id = (val & ( << i)) > ;
if (p->pNext[id] == NULL) {
p->pNext[id] = create();
}
p = p->pNext[id];
p->cnt++;
}
return ;
}
LL find(struct node *T, int val) {
struct node *p = T;
LL ans = ;
if (p == NULL) return ans;
for (int i = ; i >= ; --i) {
int id = (val & ( << i)) > ;
int id_k = (k & ( << i)) > ;
if (id_k == ) {
if (p->pNext[!id] != NULL)
ans += p->pNext[!id]->cnt; //这边的树全部都可以
if (p->pNext[id] == NULL) return ans;
p = p->pNext[id]; //如果走到了叶子节点,我这里return了,不会重复增加
} else { //id_k = 1
if (p->pNext[!id] == NULL) return ans;
p = p->pNext[!id];
}
}
return ans + p->cnt; //叶子节点有可能没算到,参考样例1
}
void work() {
scanf("%d%d", &n, &k);
for (int i = ; i <= n; ++i) {
scanf("%d", &a[i]);
sum[i] = sum[i - ] ^ a[i];
// cout << sum[i] << " ";
}
// printf("%d\n", 1 << 30);
struct node *T = NULL; insert(&T, sum[]);
LL ans = ;
for (int i = ; i <= n; ++i) {
ans += find(T, sum[i]);
insert(&T, sum[i]);
// cout << find(T, sum[i]) << endl;
}
for (int i = ; i <= n; ++i) ans += sum[i] >= k;
cout << ans << endl;
return;
}
int main() {
#ifdef local
freopen("data.txt","r",stdin);
#endif
work();
return ;
}
E. Beautiful Subarrays 字典树的更多相关文章
- Educational Codeforces Round 12 E. Beautiful Subarrays 字典树
E. Beautiful Subarrays 题目连接: http://www.codeforces.com/contest/665/problem/E Description One day, ZS ...
- Codeforces 665E. Beautiful Subarrays (字典树)
题目链接:http://codeforces.com/problemset/problem/665/E (http://www.fjutacm.com/Problem.jsp?pid=2255) 题意 ...
- codeforces 665E E. Beautiful Subarrays(trie树)
题目链接: E. Beautiful Subarrays time limit per test 3 seconds memory limit per test 512 megabytes input ...
- Beautiful Subarrays
Beautiful Subarrays time limit per test 3 seconds memory limit per test 512 megabytes input standard ...
- 【Codeforces】665E Beautiful Subarrays
E. Beautiful Subarrays time limit per test: 3 seconds memory limit per test: 512 megabytes input: st ...
- 萌新笔记——用KMP算法与Trie字典树实现屏蔽敏感词(UTF-8编码)
前几天写好了字典,又刚好重温了KMP算法,恰逢遇到朋友吐槽最近被和谐的词越来越多了,于是突发奇想,想要自己实现一下敏感词屏蔽. 基本敏感词的屏蔽说起来很简单,只要把字符串中的敏感词替换成"* ...
- [LeetCode] Implement Trie (Prefix Tree) 实现字典树(前缀树)
Implement a trie with insert, search, and startsWith methods. Note:You may assume that all inputs ar ...
- 字典树+博弈 CF 455B A Lot of Games(接龙游戏)
题目链接 题意: A和B轮流在建造一个字,每次添加一个字符,要求是给定的n个串的某一个的前缀,不能添加字符的人输掉游戏,输掉的人先手下一轮的游戏.问A先手,经过k轮游戏,最后胜利的人是谁. 思路: 很 ...
- 萌新笔记——C++里创建 Trie字典树(中文词典)(一)(插入、遍历)
萌新做词典第一篇,做得不好,还请指正,谢谢大佬! 写了一个词典,用到了Trie字典树. 写这个词典的目的,一个是为了压缩一些数据,另一个是为了尝试搜索提示,就像在谷歌搜索的时候,打出某个关键字,会提示 ...
随机推荐
- 在CentOS 7上安装Node.js的4种方法(包含npm)
Node.js和Javascript有着千丝万缕的联系,可以说Node.js让Javascript显得从未如此强大.好吧…微魔其实是个门外汉…但是这并不能阻碍微魔学习探索未知的信心~今天在国外闲逛,看 ...
- 2.JasperReports学习笔记2-创建简单的报表例子
转自:http://www.blogjava.net/vjame/archive/2013/10/12/404908.html 一.创建简单的jrxml文件 这里可以手动创建jrxml文件,也可以使用 ...
- VIsual Studio 2010 常用快捷键
1.Ctrl+S 保存 2.Ctrl+F: 查找 3.Ctrl+H: 替换 4.Ctrl+E,S: 查看空白 5.Ctrl+K+C: 注释选定内容 6.Ctrl+K+U: 取消选定注释内容 7.C ...
- 【问题】Expandable数据集的定义的正确方法,TabActivity弃用替代,Gallery替代,imageswitcher
Expandable 问题: http://www.cnblogs.com/xingyyy/p/3389611.html 扩展阅读:http://blog.csdn.net/lmj623565791/ ...
- 07_ddms透视图介绍
通过ADB(Android Debug Bridge)安卓调试桥把你的Eclipse(集成开发环境)和你的设备连接在一起.有时候ADB可能会被其他的东西占用.例如WPS会跟你抢ADB(抢端口).如果你 ...
- 树莓派 Learning 002 装机后的必要操作 --- 02 解决中文问题
树莓派 装机后的必要操作 - 解决中文问题 我的树莓派型号:Raspberry Pi 2 Model B V1.1 装机系统:NOOBS v1.9.2 每一块树莓派,装机后都应该执行的步骤 刚装机后, ...
- CentOS 6.5 and Ubuntu 14.04 使用外部邮箱发送邮件
我们可以使用外部邮箱(163,126,gmail,139等等)为我们发邮件 for CentOS 6.5 yum -y install mailx vi /etc/mail.rc 在文件的末行添加以下 ...
- 6、R语言绘制带errorbar 的柱状图
转载:http://www.cnblogs.com/xudongliang/p/7283733.html data <- data.frame(mean = c(10, 15), sd = c( ...
- java多态和强制类型转换
子类可以赋值给超类,称之为向上转型,这个是自动的. 超类不可以赋值给子类,这个是向下转型,需要我们手动实现. 赋值给超类的子类引用在运行期间将表现出不同的特性,这就是多态. 小类型 可转换为 ...
- 6.(转载)SSRF漏洞挖掘经验
SSRF 漏洞的寻找 一.从WEB功能上寻找 我们从上面的概述可以看出,SSRF是由于服务端获取其他服务器的相关信息的功能中形成的,因此我们大可以 列举几种在web 应用中常见的从服务端获取其他服务器 ...