BZOJ3689 异或之
来源:互联网 发布:unity3d raycasthit2d 编辑:程序博客网 时间:2024/04/28 14:31
题目大意:给定n个非负整数A[1], A[2], ……, A[n]。
对于每对(i, j)满足1 <= i < j <= n,得到一个新的数A[i] xor A[j],这样共有n*(n-1)/2个新的数。求这些数(不包含A[i])中前k小的数。
对于每对(i, j)满足1 <= i < j <= n,得到一个新的数A[i] xor A[j],这样共有n*(n-1)/2个新的数。求这些数(不包含A[i])中前k小的数。
注:xor对应于pascal中的“xor”,C++中的“^”。
思路:同NOI2010超级钢琴。http://blog.csdn.net/wyfcyx_forever/article/details/40400327
我们只需一开始在全局堆中放进去每个数和他之后的数异或的最小值,然后在每次出堆的的时候再放进堆中第k+1小值即可。这样重复k次。
那么问题就变成了快速求某段区间给定一个数进行xor的第k小值,我们利用可持久化trie维护size直接在树上二分即可。
时间复杂度依旧O(klogn).
Code:
#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std; #define N 100010int w[N]; int ch[N<<5][2], size[N<<5], ind;int root[N];int Newadd(int Last, int bit, int x) { int q = ++ind; ch[q][0] = ch[Last][0], ch[q][1] = ch[Last][1]; size[q] = size[Last] + 1; if (bit < 0) return q; if ((x >> bit) & 1) ch[q][1] = Newadd(ch[Last][1], bit - 1, x); else ch[q][0] = Newadd(ch[Last][0], bit - 1, x); return q;}int getkth(int Left, int Right, int x, int k) { int res = 0, better; bool d; for(int dep = 30; dep >= 0; --dep) { d = (x >> dep) & 1; better = size[ch[Right][d]] - size[ch[Left][d]]; if (better >= k) Left = ch[Left][d], Right = ch[Right][d]; else Left = ch[Left][d ^ 1], Right = ch[Right][d ^ 1], res += (1<<dep), k -= better; } return res;} struct st { int end, kth, val; st(int _end = 0, int _kth = 0, int _val = 0):end(_end),kth(_kth),val(_val){} bool operator < (const st &B) const { return val < B.val; }}; #define K 250010struct Heap { st a[K]; int top; Heap():top(0){} inline void up(int x) { for(; x != 1; x >>= 1) if (a[x]<a[x>>1]) swap(a[x],a[x>>1]); else break; } inline void down(int x) { int son; for(; (x<<1)<=top; ) { son=(((x<<1)==top)||(a[x<<1]<a[(x<<1)|1]))?(x<<1):((x<<1)|1); if (a[son]<a[x]) swap(a[son],a[x]),x=son; else break; } } inline void push(const st &x) { a[++top] = x; up(top); } st Min() { return a[1]; } inline void pop() { a[1] = a[top--]; down(1); }}H; int main() { int n, k; scanf("%d%d", &n, &k); register int i, j; for(i = 1; i <= n; ++i) { scanf("%d", &w[i]); root[i] = Newadd(root[i - 1], 30, w[i]); } for(i = 2; i <= n; ++i) H.push(st(i, 1, getkth(root[0], root[i - 1], w[i], 1))); for(i = 1; i <= k; ++i) { st tmp = H.Min(); H.pop(); if (i != 1) putchar(' '); printf("%d", tmp.val); if (tmp.kth != tmp.end - 1) H.push(st(tmp.end, tmp.kth + 1, getkth(root[0], root[tmp.end - 1], w[tmp.end], tmp.kth + 1))); } return 0;}
0 0
- BZOJ3689 异或之
- 【bzoj3689】异或之 trie+堆
- 【bzoj3689】【异或之】【trie树+堆】
- [Trie树] BZOJ3689: 异或之
- [乱搞 || 可持久化字典树 堆] BZOJ3689 异或之
- bzoj3689 luogu p1337
- 数学知识之异或
- 异或之美
- 异或之
- bzoj 3689 异或之
- [BZOJ 3689]异或之
- BZOJ 3689 异或之
- 知识点总结之异或
- BZOJ 3689: 异或之
- 位运算之 C 与或非异或
- 位运算之C:与、或、非、异或
- 位运算之 C 与或非异或
- 外挂教程之异或运算分析
- Spring Security 3.x完整入门配置教程及其代码下载
- LeetCodeOJ. Single Number
- UVA - 10066 The Twin Towers
- uva11624
- 获取Magento用户登陆状态
- BZOJ3689 异或之
- 重定向和转发的区别
- MESA:谷歌揭开跨中心超速数据仓库的神秘面纱
- weblogic下部署的应用时间少8小时问题
- 自考考后总结
- Accelerated C++ 3-5章小总结
- java基础--数组(排序)
- openstack之nova-api服务流程分析
- 两只小船儿 孤孤零零 茫茫人海中多收啊的顾客