玲珑oj 1028 贪心
http://www.ifrog.cc/acm/problem/1028
很有趣的一道题,求从n个数里挑出不同的两个,使得他俩'|','&','^'后的值尽量大,求这个最大的结果。
求最大的异或值想到了trie树的一个经典操作,对于按位与,要两个位置都是1才会出现1,我们肯定要贪心操作,优先使高位为1,
这也可以在trie上完成,如果这个位置1的个数>=2,至少有两个以这个前缀开头的数字,我们就认为这个位置可以为1,再往下走考虑下一位,
如果1的个数不满足得话,说明这一位肯定是0了,此时要进行一步合并操作,将0下面的部分合并到1上,因为此位不必要是1所以0/1都可以。
对于'|',有点复杂我感觉,我们考虑遍历每个数字,是1得位我们就不必管了,然后从最高位的0开始看看是否能变为1.
例如,对于1000(2),我们首先找有没有x100(2),如果有再找x110(2),高位如果找不到了就找低位,最后得到的就是最大值,
我们预处理出每个数能拆出来的数,1001->1000,0001,1001。。。依次类推,用一个标记数组。
之后循环每一个数的时候,记录由高位到低位'0'出现的位置,之后贪心高位找到最大的,只要标记过这个数就表示可以进行或操作。
#include<bits/stdc++.h>
using namespace std;
int num[],a[];
int ch[][],cnt[],sz;
void irt(int x)
{
int p=;
for(int i=;i>=;--i){
int bit=(x&(<<i))?:;
if(ch[p][bit]==-)
{
ch[sz][]=ch[sz][]=-;
cnt[sz]=;
ch[p][bit]=sz++;
}//cout<<p<<endl;
p=ch[p][bit];
cnt[p]++;
}
}
void uno(int &x,int y)
{
if(y==-) return;
if(x==-) {ch[sz][]=ch[sz][]=-;cnt[sz]=;x=sz++;}
cnt[x]+=cnt[y];
uno(ch[x][],ch[y][]);
uno(ch[x][],ch[y][]);
}
int solve1(int n)
{
int p=,ret=;
for(int i=;i>=;--i){
if(ch[p][]!=-&&cnt[ch[p][]]>=)
ret|=(<<i);
else uno(ch[p][],ch[p][]);
p=ch[p][];
}
return ret;
} int solve2(int x)
{
int ret=,p=;
for(int i=;i>=;--i){
int bit=(x&(<<i))?:;
if(ch[p][bit^]!=-) {p=ch[p][bit^];ret|=(<<i);}
else p=ch[p][bit];
if(p==-) break;
}
return ret;
}
bool dp[(<<)];
int solve3(int n)
{
int i,j,ret=;
memset(dp,,sizeof(dp));
for(i=;i<=n;++i) dp[a[i]]=;
for(i=(<<);i>=;--i)
{
for(j=;j>=;--j)
{
if(!(i&(<<j))) dp[i]|=dp[i|(<<j)];
}
}
int t[],p=;
for(i=;i<=n;++i)
{
p=;
for(j=;j>=;--j)
if(!(a[i]&(<<j))) t[p++]=(<<j);
int x=;
for(j=;j<p;++j)
{
if(dp[x|t[j]]) x|=t[j];
}
ret=max(ret,x|a[i]);
}
return ret;
}
int main()
{
int i,j,k,n,m,t,op; // freopen("in.txt","r",stdin);
cin>>t;
for(int cas=;cas<=t;++cas)
{
sz=;
int xo=;
cin>>n>>op;
memset(num,,sizeof(num));
ch[sz][]=ch[sz++][]=-;cnt[]=;
for(i=;i<=n;++i)
{
scanf("%d",a+i);
if(op==) xo=max(xo,solve2(a[i]));
irt(a[i]);
}
printf("Case #%d: ",cas);
switch(op){
case :cout<<solve1(n)<<endl;break;
case :cout<<xo<<endl;break;
case :cout<<solve3(n)<<endl;break;
}
}
return ;
}
玲珑oj 1028 贪心的更多相关文章
- 玲珑学院OJ 1028 - Bob and Alice are playing numbers 字典树,dp
http://www.ifrog.cc/acm/problem/1028 题解处:http://www.ifrog.cc/acm/solution/4 #include <cstdio> ...
- Light OJ 1028 - Trailing Zeroes (I) (数学-因子个数)
题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1028 题目大意:n除了1有多少个因子(包括他本身) 解题思路:对于n的每个因子 ...
- 玲珑oj 1117 线段树+离线+离散化,laz大法
1117 - RE:从零开始的异世界生活 Time Limit:1s Memory Limit:256MByte Submissions:438Solved:68 DESCRIPTION 486到了异 ...
- 九度OJ 1028:继续畅通工程 (最小生成树)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3140 解决:1338 题目描述: 省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有 ...
- oj教程--贪心
贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解. 贪心算法不是对所有问题都能得到整体最优解,关键是 ...
- SWUST OJ(1028)
特定字符序列的判断 #include <iostream> #include <cstdlib> #include <stack> #include <str ...
- 玲珑OJ 1129 - 喵哈哈村的战斗魔法师丶坏坏い月
1129 - 喵哈哈村的战斗魔法师丶坏坏い月 Time Limit:3s Memory Limit:256MByte Submissions:315Solved:71 DESCRIPTION 坏坏い月 ...
- 玲珑oj 1121 思维
1121 - Reverse the lights Time Limit:2s Memory Limit:256MByte Submissions:376Solved:111 DESCRIPTION ...
- 玲珑oj 1128 RMQ模板
1128 - 咸鱼拷问 Time Limit:3s Memory Limit:128MByte Submissions:380Solved:118 DESCRIPTION 给你两个序列A,B.每个序列 ...
随机推荐
- SMO算法精解
本文参考自:https://www.zhihu.com/question/40546280/answer/88539689 解决svm首先将原始问题转化到对偶问题,而对偶问题则是一个凸二次规划问题,理 ...
- win7 64bits下编译libjpeg库
一.下载源代码.下载地址:http://www.ijg.org/.注意:一定要下载win32 版本二.编译源代码. 1.解压源代码,(不需要修改,修改报错)修改源代码中jconfig.vc ...
- es6的Set和Map数据结构
Set 和 Map 数据结构 Set WeakSet Map WeakMap Set § ⇧ 基本用法 ES6 提供了新的数据结构 Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set ...
- SHUOJ - 算法题1 矩阵连乘问题(区间dp)
链接:http://acmoj.shu.edu.cn/problem/24/ 分析:设\(dp[i][j]\)为矩阵\(A[i:j]\)所需的最少乘法次数,则有dp方程:\(dp[i][j]=min\ ...
- grpc入门(三)
grpc入门(三) 一.介绍 本文是关于grpc的第三篇博文,是对前两篇博文的具体代码实现,秉着个人一贯的风格,没有太多抒情和总结,直接就上代码. 文章代码参考:https://github.com/ ...
- Linux远程管理器xshell和xftp使用教程,以及遇到关闭Xshell后项目也停止的解决方法
1.xshell 是一个强大的安全终端模拟软件,它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET 协议. 2.是一个基于 MS windows 平台的功能强大的 ...
- Java硬件同步机制Swap指令模拟+记录型信号量模拟
学校实验存档//.. 以经典的生产者消费者问题作为背景. 进程同步方式接口: package method; /** * P表示通过,V表示释放 */ public interface Method ...
- PHP 实现归并排序算法
算法原理 原理: 利用递归,先拆分.后合并.再排序. 步骤: 均分数列为两个子数列 递归重复上一步骤,直到子数列只有一个元素 父数列合并两个子数列并排序,递归返回数列 代码实现 // 归并排序主程序 ...
- mysql5.6备份
备份之前: 最初的二进制信息: mysql> show master logs; +------------------+-----------+ | Log_name | File_size ...
- c#结构体和字节流之间的相互转换
结构体转byte数组 1 首先要明白 ,是 在那个命名空间下 System.Runtime.InteropServices; 2 首先得到结构体的大小 2 开辟相应的内存空间 3 将结构体填 ...