题意:定义新的排序:先按一个数中二进制中1的个数从小到大排序,如果1的个数相同则按数的大小从小到大排序。问[A,B]之间有第K大的数是哪个。-2^31<=A,B<=2^31(A,B必定同正负,负数的二进制与它相反数的二进制相加=2^32)

题解:

负数可以直接+2^31-1转化为正数。

先确定答案中1的个数:依次统计区间[m,n]内二进制表示中含1的数量为0,1,2,…的数,直到累加的答案超过k,则当前值就是答案含1的个数,假设是ind。

怎么求?就先确定当前位填什么,然后后面还有多少个1可以填,组合数弄一下。

同时,我们也求出了答案是第几个[m,n]中含ind个1的数。因此,只需二分答案,求出[m,ans]中含s个1 的数的个数进行判断即可。

这个二分需要不断往左端点靠,假设答案是ans,ans+1也含有跟ans一样的还有ind个1的数的个数。

spoj1182(输入是十进制)

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std; typedef long long LL;
const int N=;
const LL MX=(1LL<<);
LL X,Y,K,c[N][N]; void myswap(LL &x,LL &y){LL t;t=x;x=y;y=t;return;} void find_c()
{
memset(c,,sizeof(c));
c[][]=;
for(int i=;i<=;i++)
{
c[i][]=;
for(int j=;j<=i;j++) c[i][j]=c[i-][j]+c[i-][j-];
}
} LL find_k(LL x,int ind,int k)//0~x how many numbers has k '1's;
{
if(ind== && k==) return ;
if(x< || ind== || k<) return ;
LL t=1LL<<(ind-);
if(x&t) return c[ind-][k]+find_k(x,ind-,k-);
else return find_k(x,ind-,k);
} int main()
{
freopen("a.in","r",stdin);
// freopen("me.out","w",stdout);
int T;
scanf("%d",&T);
find_c();
while(T--)
{
scanf("%lld%lld%lld",&X,&Y,&K);
if(X<) X=MX+X;
if(Y<) Y=MX+Y;
if(X>Y) myswap(X,Y); LL sum=,ind=,now,k;
for(int i=;i<=;i++)
{
now=find_k(Y,,i)-find_k(X-,,i);
if(sum+now<K) sum+=now,ind=i;
else {k=K-sum;break;}
}
ind++;
// printf("ind = %lld k = %lld\n",ind,k);
LL l=X,r=Y,mid;
while(l<r)
{
mid=(l+r)/;
now=find_k(mid,,ind)-find_k(X-,,ind);
// printf("mid = %lld now = %lld %lld\n",mid,now,find_k(mid,32,ind));
if(now<k) l=mid+;
else r=mid;
}
printf("%d\n",l); }
return ;
}

usaco (usaco上输入输出都是二进制形式)

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std; typedef long long LL;
const int N=;
const LL MX=(1LL<<);
LL X,Y,K,c[N][N],d[N],bit[N];
char s[]; void myswap(LL &x,LL &y){LL t;t=x;x=y;y=t;return;} void find_c()
{
memset(c,,sizeof(c));
c[][]=;
for(int i=;i<=;i++)
{
c[i][]=;
for(int j=;j<=i;j++) c[i][j]=c[i-][j]+c[i-][j-];
}
} LL find_k(LL x,int ind,int k)//0~x how many numbers has k '1's;
{
if(ind== && k==) return ;
if(x< || ind== || k<) return ;
LL t=1LL<<(ind-);
if(x&t) return c[ind-][k]+find_k(x,ind-,k-);
else return find_k(x,ind-,k);
} LL read()
{
scanf("%s",s);
LL x=;int l=strlen(s);
for(int i=l-;i>=;i--)
{
if(s[i]=='') x+=bit[l-i-];
}
return x;
} int main()
{
// freopen("a.in","r",stdin);
freopen("cowq.in","r",stdin);
freopen("cowq.out","w",stdout);
find_c();
bit[]=;
for(int i=;i<=;i++) bit[i]=bit[i-]*; X=read();
Y=read();
scanf("%lld",&K);
// printf("X = %lld Y = %lld\n",X,Y);
// scanf("%lld",&X,&Y,&K);
if(X<) X=MX+X;
if(Y<) Y=MX+Y;
if(X>Y) myswap(X,Y); LL sum=,ind=,now,k;
for(int i=;i<=;i++)
{
now=find_k(Y,,i)-find_k(X-,,i);
if(sum+now<K) sum+=now,ind=i;
else {k=K-sum;break;}
}
ind++;
// printf("ind = %lld k = %lld\n",ind,k);
LL l=X,r=Y,mid,p=find_k(X-,,ind);
while(l<r)
{
mid=(l+r)/;
now=find_k(mid,,ind)-p;
// if(now<k) l=mid+1;
if(now<k) l=mid+;
if(now>=k) r=mid;
}
// printf("%d\n",l);
int x=;
while(l)
{
d[++x]=l%;
l/=;
}
for(int i=x;i>=;i--) printf("%d",d[i]);printf("\n");
return ;
}

【spoj1182/usaco-Cow Queueing, 2003 Dec-二进制编号】数位dp的更多相关文章

  1. Pair(二进制处理+数位dp)(2019牛客暑期多校训练营(第七场))

    示例: 输入: 33 4 24 5 27 8 5 输出:5 7 31 题意:存在多少对<x,y>满足x&y>C或x^y<C的条件.(0<x<=A,0< ...

  2. bzoj3209 花神的数论题 (二进制数位dp)

    二进制数位dp,就是把原本的数字转化成二进制而以,原来是10进制,现在是二进制来做,没有想像的那么难 不知到自己怎么相出来的...感觉,如果没有一个明确的思路,就算做出来了,也并不能锻炼自己的能力,因 ...

  3. BZOJ3329: Xorequ(二进制数位dp 矩阵快速幂)

    题意 题目链接 Sol 挺套路的一道题 首先把式子移一下项 \(x \oplus 2x = 3x\) 有一件显然的事情:\(a \oplus b \leqslant c\) 又因为\(a \oplus ...

  4. 数位dp(二进制01问题)

    http://poj.org/problem?id=3252 题意:给你一个区间,求区间有多少个满足条件的数.条件是:把该数转为二进制后,如果0的数量大于等于1的数量,则为满足条件的数量. 题解:数位 ...

  5. hdu5432Rikka with Array (数位dp+十进制转化为二进制)

    Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...

  6. USACO Cow Contest

    洛谷 P2419 [USACO08JAN]牛大赛Cow Contest https://www.luogu.org/problemnew/show/P2419 JDOJ 2554: USACO 200 ...

  7. USACO Cow Cars

    洛谷 P2909 [USACO08OPEN]牛的车Cow Cars https://www.luogu.org/problemnew/show/P2909 JDOJ 2584: USACO 2008 ...

  8. USACO Cow Frisbee Team

    洛谷 P2946 [USACO09MAR]牛飞盘队Cow Frisbee Team 洛谷传送门 JDOJ 2632: USACO 2009 Mar Silver 2.Cow Frisbee Team ...

  9. USACO Cow Pedigrees 【Dp】

    一道经典Dp. 定义dp[i][j] 表示由i个节点,j 层高度的累计方法数 状态转移方程为: 用i个点组成深度最多为j的二叉树的方法树等于组成左子树的方法数 乘于组成右子树的方法数再累计. & ...

随机推荐

  1. alpha阶段个人总结(201521123034陈凯欣)

    一.个人总结 第 0 部分:基本数据结构和算法问题 大二的时候上过数据结构课,感觉自己没有学的太深入,就如之前结对编程时候四则运算有用到的二叉树来解决问题,对于二叉树就有个模糊的概念,实际动手操作起来 ...

  2. PAT L2-028 秀恩爱分得快

    https://pintia.cn/problem-sets/994805046380707840/problems/994805054698012672 古人云:秀恩爱,分得快. 互联网上每天都有大 ...

  3. python爬虫--打开爬取页面

    def requests_view(response): import webbrowser requests_url = response.url base_url = '<head>& ...

  4. python 查看趴下来的数据

    #coding=utf-8 import re from lxml import etree import requests def requests_view(response): import w ...

  5. cacti安装spine 解决WARNING: Result from CMD not valid. Partial Result: U错误

    安装spine用来替换cacti原本的执行方式,需要的包在附件中,请注意spine的安装包和你安装的cacti版本不用相同,最好是最新的spine 1.安装gcc #yum install -y gc ...

  6. MongoDB、ElasticSearch、Redis、HBase这四种热门数据库的优缺点及应用场景

    MongoDB MongoDB是当今最火爆的NoSQL数据库.MongoDB最早在09年发布,算得上是早期大数据时代的数据库代表作了.随着MongoDB的火爆,研发MongoDB的团队还专门成立了Mo ...

  7. dwarf是如何处理栈帧的?

    dwarf是如何处理栈帧的? DW_AT_frame_base 表明函数栈帧的起始点 95 < 1><0x000000ca>    DW_TAG_subprogram 96   ...

  8. [STL] map,multimap,unordered_map基本用法

    map的特性是,所有元素都会根据元素的键值自动被排序.map的所有元素都是pair,同时拥有键值(key)和实值(value).pair的第一元素被视为键值,第二元素被视为实值.map不允许两个元素拥 ...

  9. [Leetcode] 1.Two Sum(unordered_map)

    1.首先想到的方法就是两个for循环全部遍历,代码如下,可通过,但效率太低 class Solution { public: vector<int> twoSum(vector<in ...

  10. Andorid API Package ---> android.accessibilityservice

    包名: android.accessibilityservice                     Added in API level 4 URL:http://developer.andro ...