题目大意:你要找出一个有$k$个的本质不同的$n$位二进制数的集合,使得集合中最大的数最小,请输出这个数

本质不同定义:对于一个数$k$,$rev(k)$,$~k$,$rev(~k)$与$k$本质相同。其中$~k$表示对$k$的每一位二进制翻转,$rev(k)$表示对$k$左右翻转。

举个例子:对于数0001,它与1000,1110,0111本质相同。

数据范围:$n≤25,k≤10^{16}$。

此题貌似正解是数位dp,然而我比较菜。

看到这一题:打表啊!

于是打了个表,发现:

若$k≤2^{\lceil \frac{n}{2} \rceil}-2$,则直接输出$k$就可以了,证明显然。

若$k>2^{\lceil \frac{n}{2} \rceil}-2$

先考虑$n$为偶数的情况,我们打一个表,打出所有满足$rev(x)<x$或$(~x)<x$或$rev(~x)<x$的数,大概长这样

我们发现:以中间的分界线为界,当左侧构成的数去掉前导零后构成$x$,那么以$x$开头的不符合要求的二进制数就有$2x$个。

(感兴趣的同学可以证明一下,我懒得证了23333)

我们基于这一个特征,先确定这个二进制数的前$\frac{n}{2}$位。

后面的$\frac{n}{2}$位直接暴力枚举然后再随便判断一下就好了。

n为奇数的情况相似

以中间为分界线,当右侧横线左侧的数为$x$时,以$x$为前缀的$n$位二进制数有$x$个。

和之前的搞法一样随便搞一搞就可以了。

时间复杂度:$O(2^{n/2})$,空间复杂度:$O(2^{n/2})$。

  1. #include<bits/stdc++.h>
  2. #define L long long
  3. using namespace std;
  4.  
  5. int rev[<<]={};
  6. L n,k;
  7.  
  8. void out(L k1){for(L i=;i<n;i++) printf("%d",bool((1LL<<(n-i-))&k1));}
  9.  
  10. void SolveEven(){
  11. L n2=n/,s=<<n2,all=1LL<<n;
  12. if(k<s){
  13. out(k);
  14. return;
  15. }else k-=s;
  16. for(int i=;i<s;i++) rev[i]=(rev[i>>]>>)|((i&)?(s>>):);
  17. for(int i=,j=;i<s;i++,j+=){
  18. if(k>=s-j) k-=s-j;
  19. else{
  20. int p; for(p=;p<s&&k>=;p++){
  21. L k1=(1LL*i)<<n2|p;
  22. L k2=(1LL*rev[p])<<n2|rev[i];
  23. L k3=(1LL*rev[(s--p)&(s-)])<<n2|rev[s--i];
  24. if(k2>=k1&&k3>=k1)
  25. k--;
  26. }
  27. L k1=(1LL*i)<<n2|(p-);
  28. out(k1);
  29. return;
  30. }
  31. }
  32. cout<<-<<endl;
  33. }
  34. void SolveOdd(){
  35. L n2=n/,s=<<n2,all=1LL<<n;
  36. L N2=(n+)/,S=<<N2;
  37. if(k<S-){
  38. out(k);
  39. return;
  40. }else k-=S-;
  41. for(int i=;i<s;i++) rev[i]=(rev[i>>]>>)|((i&)?(s>>):);
  42. for(int i=,j=;i<s;i++,j++){
  43. if(k>=s-j) k-=s-j;
  44. else{
  45. int p; for(p=;p<s&&k>=;p++){
  46. L k1=(1LL*i)<<n2|p;
  47. L k2=((i&)<<n2)|((1LL*rev[p])<<N2)|rev[i>>];
  48. L k3=(((i&)==)<<n2)|((1LL*rev[(s-p-)&(s-)])<<N2)|rev[s--(i>>)];
  49. if(k2>=k1&&k3>=k1)
  50. k--;
  51. }
  52. L k1=(1LL*i)<<n2|(p-);
  53. out(k1);
  54. return;
  55. }
  56. }
  57. cout<<-<<endl;
  58. }
  59.  
  60. int main(){
  61. cin>>n>>k;
  62. if(n&) SolveOdd();
  63. else SolveEven();
  64. }

【xsy1281】 珠串 打表+乱搞or数位dp的更多相关文章

  1. 学渣乱搞系列之dp斜率优化

    学渣乱搞系列之dp斜率优化 By 狂徒归来 貌似dp的斜率优化一直很难搞啊,尤其是像我这种数学很挫的学渣,压根不懂什么凸包,什么上凸下凸的,哎...说多了都是泪,跟wdd讨论了下,得出一些结论.本文很 ...

  2. 老哥们,请问我做的对么?(记一次失败的st表乱搞)

    今天a开始就不是很顺,然后到d,d努力读完题理解完题意,感觉自己又行了{ 问最大的jump,我觉得如果单纯贪心策略显然会t,问min,max这类rmq果断上了st表(这东西我隔离的时候写的,没想到被拉 ...

  3. 关于一道你们眼中的水题 Windy数 的乱写(数位dp)

    啊一道水题有什么好说的 上课听不懂,下课泪两行. 有的人什么套路都会,我.. 只能可怜巴巴的抄代码,然后自己总结,顺(zhu)便(yao)颓博客 1.递推dp的思路做到一半死了,怎么也想不出来如何处理 ...

  4. HDU3652 B-number(数位DP)题解

    思路: 这里的状态分为3种,无13和末尾的1,无13且末尾为1,有13,然后DFS 等我搞清楚数位DP就来更新Orz 代码: #include<iostream> #include< ...

  5. HDU XXXX:求[L,R]的素数数量(数位DP)

    Problem G Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 131072/131072K (Java/Other) Total S ...

  6. hash进阶:使用字符串hash乱搞的姿势

    前言 此文主要介绍hash的各种乱搞方法,hash入门请参照我之前这篇文章 不好意思hash真的可以为所欲为 在开头先放一下题表(其实就是我题解中的hash题目qwq) 查询子串hash值 必备的入门 ...

  7. Luogu P1134 阶乘问题 【数学/乱搞】 By cellur925

    输入输出格式 输入格式: 仅一行包含一个正整数 NN . 输出格式: 一个整数,表示最右边的非零位的值. 输入输出样例 输入样例#1: 12 输出样例#1: 6 说明 USACO Training S ...

  8. 2016 10 28考试 dp 乱搞 树状数组

    2016 10 28 考试 时间 7:50 AM to 11:15 AM 下载链接: 试题 考试包 这次考试对自己的表现非常不满意!! T1看出来是dp题目,但是在考试过程中并没有推出转移方程,考虑了 ...

  9. bitset 的妙用:乱搞字符串匹配

    最近碰到了几次 bitset 乱搞字符串匹配的情况,故写文以记之. 1. 算法简介 核心思想:假设文本串为 \(s\),则对字符集中的每一个字符 \(c\) 开一个大小为 \(|s|\) 的 bits ...

随机推荐

  1. js 判断 undefined,单选 以及下拉框选中状态

    name = $(this).attr("title"); if(typeof(name) == 'undefined'){ alert(1); } typeof 函数 radio ...

  2. CHAPITRE II

    J'ai ainsi vécu seul, sans personne avec qui parler véritablement, jusqu'à une panne[pan][机]故障 dans ...

  3. python模块:sys

    # encoding: utf-8 # module sys # from (built-in) # by generator 1.145 """ This module ...

  4. IntelliJ IDEA 2017版 spring-boot2.0.访问jsp页面;IDE Springboot JSp 页面访问

    1.编译器设置. 生成项目后,点击file 点开Modules 选中main,右键 选择新建文件夹 选中外部 右边添加 选中项目如图: 选好后选OK退出 webapp带点了,就是成功了,在这里建立的J ...

  5. C# 编码标准(三)

    一.代码注释 1.文档型注释 该类注释采用.Net已定义好的Xml标签来标记,在声明接口.类.方法.属性.字段都应该使用该类注释,以便代码完成后直接生成代码文档,让别人更好的了解代码的实现和接口.[示 ...

  6. mac环境下配置nginx

      1.建议使用homebrew安装(ruby安装 brew install ruby)   ruby -e "$(curl -fsSL https://raw.githubusercont ...

  7. 容器,表格 ,div,元素可左右拖动,滚动 css

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8&quo ...

  8. 20155205 《Java程序设计》实验四 Android程序设计

    20155205 <Java程序设计>实验四 Android程序设计 一.实验内容及步骤 (一) Android Stuidio的安装测试 参考<Java和Android开发学习指南 ...

  9. window下切换python

    自己的win10装了2.7和3.6版本的python.本不想装2.7的,但node.js的C++的编译居然用到2.X的python,没法子就装了2.7.那怎么切换呢? 为了方便使用,我在系统的path ...

  10. (转)私有代码存放仓库 BitBucket介绍及入门操作

    转自:http://blog.csdn.net/lhb_0531/article/details/8602139 私有代码存放仓库 BitBucket介绍及入门操作 分类: 研发管理2013-02-2 ...