字典树合并 ifrog1028 Bob and Alice are playing numbers
来源:互联网 发布:网络视频服务器使用 编辑:程序博客网 时间:2024/04/30 22:04
传送门:点击打开链接
题意:有3种运算符,选择两个数使用这种运算符,使得最后的答案最大。
思路:xor的我们已经很熟练了,我们来讨论&和|
&的话,如果1的个数>=2,那么我们就走1,否则,就把字典树的01合并,因为此时01的答案是一样的。
|的话,我们需要先做一个预处理。把对于每一个节点,其1所对应的字典树复制到0所对应的字典树上去。
这一步可以用DFS搞定,复杂度是T(n)=T(n/2)+n,所以总复杂度是MAX*logMAX,max等于1e6,所以可以接受
之后,我再去枚举其中一个。对于第i位,如果是1,那么我字典树就走0,如果是0,那么我字典树就走1.
因为字典树0的里面也包括了为1的值了,现在
#include <map>#include <set>#include <cmath>#include <ctime>#include <stack>#include <queue>#include <cstdio>#include <cctype>#include <bitset>#include <string>#include <vector>#include <cstring>#include <iostream>#include <algorithm>#include <functional>#define fuck(x) cout<<"["<<x<<"]";#define FIN freopen("input.txt","r",stdin);#define FOUT freopen("output.txt","w+",stdout);//#pragma comment(linker, "/STACK:102400000,102400000")using namespace std;typedef long long LL;typedef pair<int, int>PII;const int MX = 1e5 + 5;const int MD = 2e6 + 5;const int INF = 0x3f3f3f3f;int A[MX];int n, op, root;int nxt[MD][2], End[MD], rear;int New() { rear++; End[rear] = 0; nxt[rear][0] = nxt[rear][1] = 0; return rear;}void Init() { rear = 0; root = New();}void Insert(int x) { int rt = root; for(int i = 20; i >= 0; i--) { int id = x >> i & 1; if(!nxt[rt][id]) nxt[rt][id] = New(); rt = nxt[rt][id]; End[rt]++; }}void Union(int &rt1, int rt2) { if(!rt2) return; if(!rt1) rt1 = New(); End[rt1] += End[rt2]; Union(nxt[rt1][0], nxt[rt2][0]); Union(nxt[rt1][1], nxt[rt2][1]);}int query_xor(int x) { int rt = root, ret = 0; for(int i = 20; i >= 0; i--) { int id = x >> i & 1; if(nxt[rt][id ^ 1]) { ret = ret | (1 << i); rt = nxt[rt][id ^ 1]; } else rt = nxt[rt][id]; } return ret;}int query_and() { int rt = root, ret = 0; for(int i = 20; i >= 0; i--) { if(End[nxt[rt][1]] >= 2) { rt = nxt[rt][1]; ret |= (1 << i); } else { Union(nxt[rt][0], nxt[rt][1]); rt = nxt[rt][0]; } } return ret;}int solve(int x) { int rt = root, ret = 0; for(int i = 20; i >= 0; i--) { int id = x >> i & 1; if(id == 1) { ret |= (1 << i); rt = nxt[rt][0]; } else { if(End[nxt[rt][1]]) { ret |= (1 << i); rt = nxt[rt][1]; } else rt = nxt[rt][0]; } } return ret;}void DFS(int rt) { if(!rt) return; Union(nxt[rt][0], nxt[rt][1]); DFS(nxt[rt][0]); DFS(nxt[rt][1]);}int query_or() { int ret = 0; DFS(root); for(int i = 1; i <= n; i++) { ret = max(ret, solve(A[i])); } return ret;}int main() { // FIN; int T, ansk = 0; scanf("%d", &T); while(T--) { Init(); scanf("%d%d", &n, &op); int ans = 0; for(int i = 1; i <= n; i++) { scanf("%d", &A[i]); if(op == 2) ans = max(ans, query_xor(A[i])); Insert(A[i]); } printf("Case #%d: ", ++ansk); if(op == 2) printf("%d\n", ans); else if(op == 1) printf("%d\n", query_and()); else printf("%d\n", query_or()); } return 0;}
0 0
- 字典树合并 ifrog1028 Bob and Alice are playing numbers
- lonlife oj 1029 - Bob and Alice are playing factors
- [玲珑学院OJ 1029 - Bob and Alice are playing factors]Miller_Rabin+Pollard_rho+排列组合+逆元
- 玲珑学院OJ 1029 - Bob and Alice are playing factors (大整数分解)
- Alice and Bob
- 2683. Alice and Bob
- 1798. Alice and Bob
- hdu4268 Alice and Bob
- HDU4268 Alice and Bob
- Alice, Bob and Chocolate
- hdu4268 Alice and Bob
- A:Alice and Bob
- hdu4111 Alice and Bob
- Alice and Bob
- 1798[Bob and Alice]
- Alice and Bob 数学题
- Alice and Bob
- XTU_1168 Alice and Bob
- SQL语句
- gcc编译的背后
- TreeSet的comparable接口
- 2016.9.4
- mysql 导入txt文档的问题
- 字典树合并 ifrog1028 Bob and Alice are playing numbers
- Linux用户和群组基本命令
- 直接插入排序
- CD检测代码的定位练习-20160905
- C/C++开发者必不可少的15款编译器+IDE
- const关键字
- 基于8051stc板的飞机大战
- 模块FS文件操作函数
- [算法和数据结构]之一:栈和队列简析