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 贪心的更多相关文章

  1. 玲珑学院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> ...

  2. Light OJ 1028 - Trailing Zeroes (I) (数学-因子个数)

    题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1028 题目大意:n除了1有多少个因子(包括他本身) 解题思路:对于n的每个因子 ...

  3. 玲珑oj 1117 线段树+离线+离散化,laz大法

    1117 - RE:从零开始的异世界生活 Time Limit:1s Memory Limit:256MByte Submissions:438Solved:68 DESCRIPTION 486到了异 ...

  4. 九度OJ 1028:继续畅通工程 (最小生成树)

    时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3140 解决:1338 题目描述:     省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但不一定有 ...

  5. oj教程--贪心

    贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择.也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解. 贪心算法不是对所有问题都能得到整体最优解,关键是 ...

  6. SWUST OJ(1028)

    特定字符序列的判断 #include <iostream> #include <cstdlib> #include <stack> #include <str ...

  7. 玲珑OJ 1129 - 喵哈哈村的战斗魔法师丶坏坏い月

    1129 - 喵哈哈村的战斗魔法师丶坏坏い月 Time Limit:3s Memory Limit:256MByte Submissions:315Solved:71 DESCRIPTION 坏坏い月 ...

  8. 玲珑oj 1121 思维

    1121 - Reverse the lights Time Limit:2s Memory Limit:256MByte Submissions:376Solved:111 DESCRIPTION ...

  9. 玲珑oj 1128 RMQ模板

    1128 - 咸鱼拷问 Time Limit:3s Memory Limit:128MByte Submissions:380Solved:118 DESCRIPTION 给你两个序列A,B.每个序列 ...

随机推荐

  1. 网页采集利器 phpQuery

    网页采集利器 phpQuery 2012-02-28 11:43:24|  分类: php|举报|字号 订阅     在网页采集的时候,通常都会用到正则表达式.但是有时候对于正则不太好的同学,比如我, ...

  2. 设置eclipse启动时所需要的jdk

    eclipse启动时默认的时环境变量中的JDK,但如果环境变量中的jdk版本比较低,那么eclipse是启动不了的, 比如系统中运行的程序中使用的是jdk1.7,但eclipse版本2018需要jdk ...

  3. jar打包方法使用整理

    dos窗口下操作jar:(JDK的命令) jar命令能够把Java应用打包成一个文件,这个文件的扩展名为.jar,称为JAR文件.JAR 文件非常类似 ZIP 文件.准确的说,它就是 ZIP 文件,所 ...

  4. ACM对拍程序

    1.把所需对拍的代码的可执行文件a.exe b.exe放在同一目录下 2.把rand数据的代码的可执行文件c.exe放在该目录下 3.新建一个txt文件,里面添加代码,后把格式改成bat @echo ...

  5. windows 常用cmd命令

    为了减少使用鼠标的频次,熟记一些常用应用的快捷键与系统本身常用的命令是必须的,以下记录一些常用的windows系统命令. 查看网络端口占用情况 :netstat -ano | findstr 8080 ...

  6. Hbase Region Server整体架构

    Region Server的整体架构 本文主要介绍Region的整体架构,后续再慢慢介绍region的各部分具体实现和源码 RegionServer逻辑架构图 RegionServer职责 1.    ...

  7. C++基础---结构体(struct)

    转自:http://blog.csdn.net/cainv89/article/details/48447225 1. 结构体(struct) 1.1 结构体的概念 结构体(struct):是由一系列 ...

  8. matlab基本操作总结

    1.clear;//清除工作平台变量2.close all;//关闭打开的图形窗口3.I = imread('C:\Users\dell\Desktop\rice.jpg');//读取图像,存储在I数 ...

  9. webapi 版本控制

    一.问题 软件开发过程中,常常会需要变更以前的接口,添加或删除接口请求字段,接口字段校验.甚至是变更请求/返回字段名称,如果强制要求所有客户端跟着一起升级代价太大.如果接口从一开始就考虑到了版本的设计 ...

  10. WCF基本知识

    1.开通WCF调试服务: 须在服务端的行为中作如下配置:includeExceptionDetailInFaults="true" 代码如下: <behaviors> ...