codeforces 665E (字典树)
2016-04-22 16:27
375 查看
E. Beautiful Subarrays
time limit per test
3 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output
One day, ZS the Coder wrote down an array of integers a with elements a1, a2, ..., an.
A subarray of the array a is a sequence al, al + 1, ..., ar for
some integers (l, r) such that 1 ≤ l ≤ r ≤ n.
ZS the Coder thinks that a subarray of a is beautiful if the bitwise xor of all the elements in the subarray is at least k.
Help ZS the Coder find the number of beautiful subarrays of a!
Input
The first line contains two integers n and k (1 ≤ n ≤ 106, 1 ≤ k ≤ 109)
— the number of elements in the array a and the value of the parameter k.
The second line contains n integers ai (0 ≤ ai ≤ 109)
— the elements of the array a.
Output
Print the only integer c — the number of beautiful subarrays of the array a.
Examples
input
output
input
output
input
output
题意:求出一个数组的子串使得这个子串的xor值大于等于k.
先求出每一段前缀和,等价于求多少对前缀的xor大于等于k.把前缀扫一遍,每次用利用
前缀的值和k跑字典树,前缀num和k的某一位上有4种情况,我就懒得找统一的规律了
直接讨论:
1:num和k都是1,往字典树当前节点的next[0]走;
2:num和k都是0,字典树当前节点next[1]子树的size和向next[1]走的结果相加;
3:num是1,k是0,字典树当前节点next[0]子树的size和向next[0]走的结果相加;
4:num是0,k是1,往字典树当前节点的next[1]走;
然后每次统计完把num插进字典树,更新每个节点一下的数字个数.
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
using namespace std;
#define maxn 1111111
int a[maxn];
struct node {
int next[2];
int num;
}tree[maxn*33];
int root, cnt;
int n, k;
void build_node (int c) {
if (!tree[c].next[0])
tree[c].next[0] = ++cnt, tree[tree[c].next[0]].num = 0;
if (!tree[c].next[1])
tree[c].next[1] = ++cnt, tree[tree[c].next[1]].num = 0;
}
int dfs (int u, int bit, int num) {
build_node (u);
if (tree[u].num == 0 && u != root)
return 0;
if (bit == 0) {
return tree[u].num;
}
int ans = 0;
int id1 = ((num&bit)>=1);//num当前位
int id2 = ((k&bit)>=1); //k当前位
if (id1 && id2) {
ans += dfs (tree[u].next[0], bit>>1, num);
}
else if (!id1 && !id2) {
ans += tree[tree[u].next[1]].num + dfs (tree[u].next[0], bit>>1, num);
}
else if (id1 && !id2) {
ans += tree[tree[u].next[0]].num + dfs (tree[u].next[1], bit>>1, num);
}
else {
ans += dfs (tree[u].next[1], bit>>1, num);
}
return ans;
}
void insert (int num) {
int p = root;
int bit = (1<<30);
while (bit) {
tree[p].num++;
build_node (p);
int id = ((num&bit)>=1);//当前位
p = tree[p].next[id];
bit >>= 1;
}
build_node (p);
tree[p].num++;
}
void solve () {
long long ans = 0;
root = 1;
build_node (root);
for (int i = 1; i <= n; i++) {
int p = root;
if (a[i] >= k)
ans++;
int cur = (1<<30);
int gg = dfs (p, cur, a[i]);
ans += gg;
insert (a[i]);
}
printf ("%lld\n", ans);
}
int main () {
cnt = 1;
cin >> n >> k;
for (int i = 1; i <= n; i++) {
scanf ("%d", &a[i]);
if (i > 1)
a[i] ^= a[i-1];
}
solve ();
return 0;
}
time limit per test
3 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output
One day, ZS the Coder wrote down an array of integers a with elements a1, a2, ..., an.
A subarray of the array a is a sequence al, al + 1, ..., ar for
some integers (l, r) such that 1 ≤ l ≤ r ≤ n.
ZS the Coder thinks that a subarray of a is beautiful if the bitwise xor of all the elements in the subarray is at least k.
Help ZS the Coder find the number of beautiful subarrays of a!
Input
The first line contains two integers n and k (1 ≤ n ≤ 106, 1 ≤ k ≤ 109)
— the number of elements in the array a and the value of the parameter k.
The second line contains n integers ai (0 ≤ ai ≤ 109)
— the elements of the array a.
Output
Print the only integer c — the number of beautiful subarrays of the array a.
Examples
input
3 1 1 2 3
output
5
input
3 2 1 2 3
output
3
input
3 31 2 3
output
2
题意:求出一个数组的子串使得这个子串的xor值大于等于k.
先求出每一段前缀和,等价于求多少对前缀的xor大于等于k.把前缀扫一遍,每次用利用
前缀的值和k跑字典树,前缀num和k的某一位上有4种情况,我就懒得找统一的规律了
直接讨论:
1:num和k都是1,往字典树当前节点的next[0]走;
2:num和k都是0,字典树当前节点next[1]子树的size和向next[1]走的结果相加;
3:num是1,k是0,字典树当前节点next[0]子树的size和向next[0]走的结果相加;
4:num是0,k是1,往字典树当前节点的next[1]走;
然后每次统计完把num插进字典树,更新每个节点一下的数字个数.
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
using namespace std;
#define maxn 1111111
int a[maxn];
struct node {
int next[2];
int num;
}tree[maxn*33];
int root, cnt;
int n, k;
void build_node (int c) {
if (!tree[c].next[0])
tree[c].next[0] = ++cnt, tree[tree[c].next[0]].num = 0;
if (!tree[c].next[1])
tree[c].next[1] = ++cnt, tree[tree[c].next[1]].num = 0;
}
int dfs (int u, int bit, int num) {
build_node (u);
if (tree[u].num == 0 && u != root)
return 0;
if (bit == 0) {
return tree[u].num;
}
int ans = 0;
int id1 = ((num&bit)>=1);//num当前位
int id2 = ((k&bit)>=1); //k当前位
if (id1 && id2) {
ans += dfs (tree[u].next[0], bit>>1, num);
}
else if (!id1 && !id2) {
ans += tree[tree[u].next[1]].num + dfs (tree[u].next[0], bit>>1, num);
}
else if (id1 && !id2) {
ans += tree[tree[u].next[0]].num + dfs (tree[u].next[1], bit>>1, num);
}
else {
ans += dfs (tree[u].next[1], bit>>1, num);
}
return ans;
}
void insert (int num) {
int p = root;
int bit = (1<<30);
while (bit) {
tree[p].num++;
build_node (p);
int id = ((num&bit)>=1);//当前位
p = tree[p].next[id];
bit >>= 1;
}
build_node (p);
tree[p].num++;
}
void solve () {
long long ans = 0;
root = 1;
build_node (root);
for (int i = 1; i <= n; i++) {
int p = root;
if (a[i] >= k)
ans++;
int cur = (1<<30);
int gg = dfs (p, cur, a[i]);
ans += gg;
insert (a[i]);
}
printf ("%lld\n", ans);
}
int main () {
cnt = 1;
cin >> n >> k;
for (int i = 1; i <= n; i++) {
scanf ("%d", &a[i]);
if (i > 1)
a[i] ^= a[i-1];
}
solve ();
return 0;
}
相关文章推荐
- 毕设 微信分享
- KMP
- ViewPager+Fragment以及Fragment嵌套ViewPager
- 或许我们做错了,但绝非一无是处
- android自动刷新应用内存使用状态的方法
- Android SDK Android NDK Android Studio 官方下载地址
- 内存清理sql语句
- WPF异常:在“System.Windows.Markup.StaticResourceHolder”上提供值时引发了异常。
- CoreData的一些简单运用
- 你的孤独,虽败犹荣 摘抄
- 欢迎使用CSDN-markdown编辑器
- Java重载时的类型转换
- 【bzoj2002】[Hnoi2010]Bounce 弹飞绵羊
- Coco2d-x-2.x和3.x创建工程以及编译安卓注意事项
- 关于spring发email总结
- 利用Handler来实现UI线程的更新
- 括号配对(南阳理工2)栈
- 在Word中如何自动生成参考文献引用
- BP神经网络的网络带宽预测
- django/python日志logging 的配置以及处理