【spoj1182/usaco-Cow Queueing, 2003 Dec-二进制编号】数位dp
题意:定义新的排序:先按一个数中二进制中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的更多相关文章
- 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< ...
- bzoj3209 花神的数论题 (二进制数位dp)
二进制数位dp,就是把原本的数字转化成二进制而以,原来是10进制,现在是二进制来做,没有想像的那么难 不知到自己怎么相出来的...感觉,如果没有一个明确的思路,就算做出来了,也并不能锻炼自己的能力,因 ...
- BZOJ3329: Xorequ(二进制数位dp 矩阵快速幂)
题意 题目链接 Sol 挺套路的一道题 首先把式子移一下项 \(x \oplus 2x = 3x\) 有一件显然的事情:\(a \oplus b \leqslant c\) 又因为\(a \oplus ...
- 数位dp(二进制01问题)
http://poj.org/problem?id=3252 题意:给你一个区间,求区间有多少个满足条件的数.条件是:把该数转为二进制后,如果0的数量大于等于1的数量,则为满足条件的数量. 题解:数位 ...
- hdu5432Rikka with Array (数位dp+十进制转化为二进制)
Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, so he ...
- USACO Cow Contest
洛谷 P2419 [USACO08JAN]牛大赛Cow Contest https://www.luogu.org/problemnew/show/P2419 JDOJ 2554: USACO 200 ...
- USACO Cow Cars
洛谷 P2909 [USACO08OPEN]牛的车Cow Cars https://www.luogu.org/problemnew/show/P2909 JDOJ 2584: USACO 2008 ...
- USACO Cow Frisbee Team
洛谷 P2946 [USACO09MAR]牛飞盘队Cow Frisbee Team 洛谷传送门 JDOJ 2632: USACO 2009 Mar Silver 2.Cow Frisbee Team ...
- USACO Cow Pedigrees 【Dp】
一道经典Dp. 定义dp[i][j] 表示由i个节点,j 层高度的累计方法数 状态转移方程为: 用i个点组成深度最多为j的二叉树的方法树等于组成左子树的方法数 乘于组成右子树的方法数再累计. & ...
随机推荐
- UML建模语言入门-视图,事物,关系,通用机制
. 作者 :万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/18964835 . 一. UML视图 1. Ration ...
- iOS- 无处不在,详解iOS集成第三方登录(SSO授权登录<无需密码>)
1.前言 不多说,第三登录无处不在!必备技能,今天以新浪微博为例. 这是上次写的iOS第三方社交分享:http://www.cnblogs.com/qingche/p/3727559.html 可 ...
- 3dContactPointAnnotationTool开发日志(七)
调了半天发现是逻辑错误,改了一下终于没那么奇怪了: 但是有的接触点很明显跑偏了.再回顾一下自己是怎么求的,我是直接用的下面的代码求解一个点是否在另一个物体内部: var bounds = us ...
- 在mvc返回JSON时出错:序列化类型为“System.Data.Entity.DynamicProxies.Photos....这个会的对象时检测到循环引用 的解决办法
在MVC中返回JSON时出错,序列化类型为“System.Data.Entity.DynamicProxies.Photos....这个会的对象时检测到循环引用. public ActionResul ...
- matlab isfield
isfield 函数功能:判断输入是否是结构体数组的域(成员). 调用格式: tf=isfield(S,'fieldname') 检查结构体S是否包含由fieldname指定的域,如果包含,返回逻辑1 ...
- datepicker约束开始时间和结束时间
datepicker约束开始时间和结束时间作用就是:选择要搜索的日期范围. <!DOCTYPE html> <html lang="en"> <hea ...
- Python面向对象—类的继承
一个子类可以继承父类的所有属性,不管是父类的数据属性还是方法. class Father(object): num = 0 def __init__(self): print "I'm Pa ...
- 进程池-限制同一时间在CPU上运行的进程数
if __name__=='__main__' : 为了区分你是主动执行这个脚本,还是从别的地方把它当做一个模块去调用. 如果是主动执行,则执行.如果是调用的,则不执行主体. 1. 串行:切记切记: ...
- CentOS7 从查看、启动、停止服务说起systemctl
执行命令“systemctl status 服务名.service”可查看服务的运行状态,其中服务名后的.service 可以省略,这是CenOS7以后采用systemd作为初始化进程后产生的变化. ...
- I/O复用----poll
2018-08-01 (星期三)poll(): #include <sys/poll.h> int poll (struct pollfd *fd, unsigned int nfds, ...