题目

低智选手果然刷不动uoj

首先考虑一下构造一棵树显然是骗你玩的,按位与这个东西越做越小,挂到链的最下面显然不会劣于挂到之前的某一个点下面,所以我们只需要求一个排列使得答案最小就好了

设\(A=\max(a_i)\),发现最优答案不可能要劣于反复对一个数取\(\rm and\)的答案,我们就有了一个\(O(nA)\)的暴力,设\(dp_i\)表示当前的\(\rm and\)和为\(i\),把这个\(i\)变成\(0\)的最小代价

但是有可能最后的\(\rm and\)和也不是\(0\),于是我们把所有\(a_i\)都共有的二进制位\(k\)都求出来,在把每一个\(a_i\)消去这些数位,即和\(k\)异或一下,最后的\(\rm and\)和就一定为\(0\);在答案加上\(n\times k\)就好了

这样的话转移非常简单,我们枚举一个\(a_j\),\(dp_i=\min(dp_{i\ \rm and \ a_j }+i\ \rm and \ a_j)\)即可

最后答案是\(\min(dp_{a_i}+a_i)\)

注意到\(i\ \rm and \ a_j\)一定是\(i\)的子集,考虑枚举\(i\)的子集\(j\),现在只需要判断是否存在一个\(a_k\)满足\(i\ \rm and\ \ a_k=j\)

从集合的角度来考虑,我们可以把上面那个条件拆成\(j\)是\(a_k\)的子集,并且\(a_k\)是\(j\bigoplus i\)在全集补集中的子集,我们用\(\rm fwt\)处理一下就可以知道是否有一个\(a_k\)是\(i\bigoplus j\)在全集补集中的子集,但并没有办法判断\(j\)是否为\(a_k\)的子集

但是想一想发现我们没有必要判断\(j\)是否为\(a_k\)的子集,只管转移就好了

观察转移式\(dp_i=\min(dp_j+j)\),显然\(j\)越小越好,如过存在\(a_k\)是\(i\bigoplus j\)在全集补集中的子集,但是\(a_k\)并不是\(j\)的子集,那么一定会有一个更小的\(i\)的子集是这个\(a_k\)的子集,那个转移一定更优

于是复杂度就是\(O(3^{\log A})\)

#include<bits/stdc++.h>
#define re register
#define LL long long
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
inline int read() {
char c=getchar();int x=0;while(c<'0'||c>'9') c=getchar();
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x;
}
const int maxn=1e5+5;
int n,a[maxn],vis[1<<18+1],k,T,len;
LL dp[1<<18+1],ans;
int main() {
n=read();
for(re int i=1;i<=n;i++) a[i]=read(),T=max(T,a[i]);
len=1;while(len<T) len<<=1;len--;
for(re int i=1;i<=n;i++) vis[a[i]]=1;
for(re int i=2;i<=len+1;i<<=1)
for(re int ln=i>>1,l=0;l<len;l+=i)
for(re int x=l;x<l+ln;++x) vis[x+ln]|=vis[x];
k=a[1];for(re int i=2;i<=n;i++) k&=a[i];
for(re int i=1;i<=n;i++) a[i]^=k;
memset(dp,20,sizeof(dp));
ans=dp[0];dp[0]=0;
for(re int i=1;i<=T;i++)
for(re int j=i;j;j=(j-1)&i)
if(vis[len^j]&&dp[i^j]+(i^j)<dp[i]) dp[i]=dp[i^j]+(i^j);
for(re int i=1;i<=n;i++)
ans=min(ans,dp[a[i]]+a[i]);
printf("%lld\n",1ll*n*k+ans);
return 0;
}

最新文章

  1. Core Data的简单用法
  2. SQL注入自学[第二学:注入环境的简单突破]
  3. Tomcat系列之Java技术详解
  4. 安装hadoop-2.3.0-cdh5.1.2全过程
  5. 使用Join代替In
  6. su:认证失败
  7. hdu 2544 最短路 Dijkstra
  8. hadoop浅尝 第一个hadoop程序
  9. sublime text3安装SublimeREPL--解决不能运行input()的问题
  10. 来自投资银行的20个Java面试题
  11. 【HDOJ】4982 Goffi and Squary Partition
  12. 对话框(alert,prompt,confirm,showModalDialog)
  13. 《转载》使用CSS3 Flexbox布局
  14. 关于jq操作table下多个type=radio的input的选中
  15. MVC 前端页面ViewData参数名不区分大小写
  16. Bootstrap switch 切换状态踩坑
  17. Python Gevent协程自动切换IO
  18. c# 抽象类 抽象函数 接口
  19. Java中带包(创建及引用)的类的编译
  20. Docker技术入门与实战 第二版-学习笔记-4-Dockerfile外其他生成镜像的方法

热门文章

  1. javafx教程大全
  2. NX二次开发-UFUN高亮显示对象UF_DISP_set_highlight
  3. 微信-小程序-开发文档-服务端-模板消息:templateMessage.addTemplate
  4. (转)AttributeError: module &#39;tkinter&#39; has no attribute &#39;messagebox&#39;
  5. i++ 和 ++i 的区别
  6. 剑指offer——05重建二叉树
  7. Spring Cloud Feign设计原理
  8. 使用PyCharm创建Django项目及基本配置
  9. jq的绑定动态元素
  10. WIN10安装CUDA10 cuDNN