SPOJ SUBXOR

题意

给定一个由正整数构成的数组, 求 异或和小于k 的子序列的个数.

题解

假设答案区间为 [L, R], XOR[L, R] 等价于 XOR[1, L - 1] ^ XOR[1, R], 可以使用 01Trie 保存目前已有的 前缀异或和, 对于每一个新的前缀插入之前, 在 01Trie 中查询 与 新的前缀 异或值 小于 K 的 已有前缀和的个数.

对于每个TrieNode 的定义为

struct TrieNode {
TrieNode* next[2];
int cnt;
TrieNode() {
next[0] = next[1] = NULL;
// 保存当前前缀的个数
cnt = 0;
}
};

在进行查询时, 比较 新的前缀和 and k 的每一位

已有前缀和的第 i 位 indexPre( 新的前缀和的第 i 位) indexK( K 的第 i 位) 相应操作
0 0 0 递归求解左子树
1 0 1 统计左子树叶子节点个数, 递归求解右子树
1 1 0 递归求解右子树
0 1 1 统计右子树叶子节点个数, 递归求解左子树

对于 indexPre == 0, indexK == 0 的情况来说, 已有前缀和为 0 时满足条件, 因此需要递归求解左子树. 当已有前缀和为 1 时, indexK == 1, 大于要求的值, 所以不继续递归.

对于 indexPre == 0, indexK == 1 的情况来说, 已有前缀和为 1 时满足条件, 但 右子树 中可能有 值大于等于 K 的叶子节点, 因此需要递归求解右子树. 当已有前缀和为 0 时, indexK == 0, 所有左子树的叶子节点的值均小于 K, 因此统计左子树叶子节点的个数

AC代码

#include <cstdio>
#include <iostream>
using namespace std;
struct TrieNode {
TrieNode* next[2];
int cnt;
TrieNode() {
next[0] = next[1] = NULL;
cnt = 0;
}
};
void insertNum(TrieNode* root, unsigned num) {
TrieNode* p = root;
for(int i = 31; i >= 0; i--) {
int index = (num >> i) & 1;
if(!p->next[index])
p->next[index] = new TrieNode();
p = p->next[index];
p->cnt++;
}
}
int getCnt(TrieNode* root) {
return root ? root->cnt : 0;
}
int queryLessThanK(TrieNode* root, int pre, int k) {
TrieNode* p = root;
int ret = 0;
for(int i = 31; i >= 0; i--) {
if(p == NULL)
break;
int indexPre = (pre >> i) & 1; // prefiexbit
int indexK = (k >> i) & 1; // bit
if(indexPre == indexK) {
if(indexK)
ret += getCnt(p->next[1]);
p = p->next[0];
}
else if(indexPre != indexK) {
if(indexK)
ret += getCnt(p->next[0]);
p = p->next[1];
}
}
return ret;
}
int main() {
int nTest; scanf("%d", &nTest);
while(nTest--) {
int nNum, k;
scanf("%d %u", &nNum, &k);
TrieNode* root = new TrieNode();
// insertNum(root, 0) 保证了前缀异或和 pre 自身 可以小于 k
insertNum(root, 0);
unsigned pre = 0;
long long ans = 0;
while(nNum--) {
unsigned num; scanf("%u", &num);
pre = pre ^ num;
ans += queryLessThanK(root, pre, k);
insertNum(root, pre);
}
cout << ans << endl;
}
return 0;
}

SPOJ SUBXOR的更多相关文章

  1. BZOJ 2588: Spoj 10628. Count on a tree [树上主席树]

    2588: Spoj 10628. Count on a tree Time Limit: 12 Sec  Memory Limit: 128 MBSubmit: 5217  Solved: 1233 ...

  2. SPOJ DQUERY D-query(主席树)

    题目 Source http://www.spoj.com/problems/DQUERY/en/ Description Given a sequence of n numbers a1, a2, ...

  3. SPOJ GSS3 Can you answer these queries III[线段树]

    SPOJ - GSS3 Can you answer these queries III Description You are given a sequence A of N (N <= 50 ...

  4. 【填坑向】spoj COT/bzoj2588 Count on a tree

    这题是学主席树的时候就想写的,,, 但是当时没写(懒) 现在来填坑 = =日常调半天lca(考虑以后背板) 主席树还是蛮好写的,但是代码出现重复,不太好,导致调试的时候心里没底(虽然事实证明主席树部分 ...

  5. SPOJ bsubstr

    题目大意:给你一个长度为n的字符串,求出所有不同长度的字符串出现的最大次数. n<=250000 如:abaaa 输出: 4 2 1 1 1 spoj上的时限卡的太严,必须使用O(N)的算法那才 ...

  6. 【SPOJ 7258】Lexicographical Substring Search

    http://www.spoj.com/problems/SUBLEX/ 好难啊. 建出后缀自动机,然后在后缀自动机的每个状态上记录通过这个状态能走到的不同子串的数量.该状态能走到的所有状态的f值的和 ...

  7. 【SPOJ 1812】Longest Common Substring II

    http://www.spoj.com/problems/LCS2/ 这道题想了好久. 做法是对第一个串建后缀自动机,然后用后面的串去匹配它,并在走过的状态上记录走到这个状态时的最长距离.每匹配完一个 ...

  8. 【SPOJ 8222】Substrings

    http://www.spoj.com/problems/NSUBSTR/ clj课件里的例题 用结构体+指针写完模板后发现要访问所有的节点,改成数组会更方便些..于是改成了数组... 这道题重点是求 ...

  9. SPOJ GSS2 Can you answer these queries II

    Time Limit: 1000MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Description Being a ...

随机推荐

  1. IDEA创建Maven项目和子模块

    一.新建Project a. 新建项目,点击Create New Project b. 选择使用maven来新建项目 选择新建Maven模块(对IDEA来说是项目) 如果Project SDK那里没有 ...

  2. 在CentOS 7下更改yum源与更新系统

    在CentOS 7下更改yum源与更新系统. [1] 首先备份/etc/yum.repos.d/CentOS-Base.repo cp /etc/yum.repos.d/CentOS-Base.rep ...

  3. 【转载】RocketMQ与Kafka对比(18项差异)

    转载自 https://github.com/alibaba/RocketMQ/wiki/rmq_vs_kafka RocketMQ与Kafka对比(18项差异) 淘宝内部的交易系统使用了淘宝自主研发 ...

  4. Eclipse自定义启动画面和状态栏图标以及各种小图标的含义

    一. 启动画面自定义 第一种情况:纯Eclipse 找到Eclipse安装路径下\eclipse\plugins\org.eclipse.platform_3.7.2.v201202080800,具体 ...

  5. 在mysql语句中为什么要加反引号

    在MySQL语句中我们有时候经常会遇到反引号(``),刚开始的时候不知道什么意思,他是什么作用呢? Select * from `member` order by posts desc limit 0 ...

  6. IO流之 commons-IO

    commons-IO 导入classpath 加入classpath的第三方jar包内的class文件才能在项目中使用 创建lib文件夹 将commons-io.jar拷贝到lib文件夹 右键点击co ...

  7. 原生JS的轮播图

    学习前端也有一小段时间了,当初在学习javascript的时候,练手的一个轮播图实例,轮播图也是挺常见的了. 着是通过获取图片偏移量实现的.也实现了无缝切换.还有一点问题就是没有加上图片切换的时候的延 ...

  8. git日常使用

    git强制回滚指定版本git reset --hard xxx(版本名) git强制推送git push -f remote(远程地址) branch(远程分支) 查看远程分支 git branch ...

  9. HTML DOM insertBefore() 方法 问题

    写即时通讯时,每次新增的回话插到原有子节点的前面. 但是出现了以下报错的情况 如图: MDC: var insertedElement = parentElement.insertBefore(new ...

  10. visual studio 2013的C++开发环境不错--vs2013安装试用手记

    原文:http://blog.csdn.net/haoyujie/article/details/24370189 从visual studio 体系,最后一次对C++实现了大的改进,那还是vs 7. ...