[BZOJ 3689]异或之
来源:互联网 发布:js获取当前页面url 编辑:程序博客网 时间:2024/04/28 06:28
Description
给定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小的数。
注:xor对应于pascal中的“xor”,C++中的“^”。
Solution
堆+Tire
如果在Tire上贪心就是求第1小(大)数啦
注意如果查询第一小数会查到他自己,所以k最好++
查询第2小就好啦~
因为查询k小,所以在每个tire的节点上维护一个size域,如果k<=当前位相同的size域的话,就往相同方向走,否则就往相反方向走,然后k减一下
首先把第一小都丢进堆里,如果pop出第k小的话就把k+1丢进去
- 为毛线我的左偏树常数那么大。。
#include <bits/stdc++.h>#define maxn 100010using namespace std;int n, k;int a[maxn];struct Node{ int l, r, dis, val, pos, kth; Node(int val = 0, int pos = 0, int kth = 0, int dis = 0, int l = 0, int r = 0): val(val), pos(pos), kth(kth), dis(dis), l(l), r(r){} bool operator<(const Node& k)const{return val < k.val;}}TMP;namespace Tire{ int t[3000000][2], size[3000000]; int root, Newnode; void Insert(int p){ int now = root; for(int i = 30; i >= 0; i --){ int q = p >> i & 1; if(!t[now][q])t[now][q] = ++ Newnode; now = t[now][q]; size[now] ++; } } int Get_Kth(int p, int k){ k ++;int ret = 0, now = root; for(int i = 30; i >= 0; i --){ int Q = p >> i & 1; if(k <= size[t[now][Q]]) now = t[now][Q]; else{ k -= size[t[now][Q]]; ret |= 1 << i; now = t[now][Q^1]; } }return ret; }}namespace Heap{ Node T[3000000]; int root, size; int merge(int a, int b){ if(!a || !b)return a + b; if(T[b] < T[a])swap(a, b); T[a].r = merge(T[a].r, b); if(T[T[a].l].dis < T[T[a].r].dis) swap(T[a].l, T[a].r); T[a].dis = T[a].r ? T[T[a].r].dis + 1 : 0; return a; } void push(int val, int pos, int kth){ T[++ size] = Node(val, pos, kth); root = merge(root, size); } void Get_pop(){ TMP = T[root]; root = merge(T[root].l, T[root].r); }}int main(){ scanf("%d%d", &n, &k); for(int i = 1; i <= n; i ++) scanf("%d", &a[i]); for(int i = 1; i <= n; i ++) Tire::Insert(a[i]); for(int i = 1; i <= n; i ++) Heap::push(Tire::Get_Kth(a[i], 1), i, 1); k <<= 1; for(int i = 1; i <= k; i ++){ Heap::Get_pop();//get_TMP if(i & 1)printf("%d ", TMP.val); if(TMP.kth != n-1) Heap::push(Tire::Get_Kth(a[TMP.pos], TMP.kth + 1), TMP.pos, TMP.kth + 1); } return 0;}
0 0
- bzoj 3689 异或之
- [BZOJ 3689]异或之
- BZOJ 3689 异或之
- BZOJ 3689: 异或之
- 【BZOJ 3689】异或之 trie+堆
- BZOJ 3689 异或之 Trie树+堆
- bzoj 3689: 异或之 字典树+堆
- BZOJ 3689: 异或之 字典树 优先队列
- BZOJ[3689] 异或之 Trie树+堆
- bzoj-4103 异或运算
- 【BZOJ】【P3689】【异或之】【题解】【可持久化Trie+堆】
- bzoj 3261: 最大异或和
- bzoj 3261: 最大异或和
- bzoj-3261 最大异或和
- BZOJ 3261 最大异或和
- bzoj 3503(解异或方程组)
- BZOJ 3261 最大异或和
- BZOJ - 3517 翻硬币(异或)
- CODEFORCES 580E Kefa and Watch
- poj1001高精度乘法
- poj 2533 Longest Ordered Subsequence 经典DP
- static( 用法看了就会的解释)extern 局部变量 全局变量联系还有auto
- Android Studio 的使用——GsonFormat插件的安装
- [BZOJ 3689]异或之
- 第四周项目二太乐了
- Ubuntu 14.04.1下打开终端的方式
- 深入理解java socket编程
- 【C】字符串逆序
- 相邻最大差值
- firefox浏览器不能使用window.close的解决方案
- Intel Edison breakout board 电源路径框图
- 哈哈