poj3252
好了,我的数论渣爆了…………
首先[n,m]内的round number显然就是f[m]-f[n-1]
即问0~x内有多少round number;
设x的二进制位数为t;
首先很好分析出在这个范围
若某数的二进制位数<t,则首位1不动,后面组合即可;
然后被卡在当二进制位数为t的round number有多少这招情况;
后来看了别人的解题报告才恍然大悟;
对于x,不算首位的1,只要把当前某一个1改成0,并对后面位数重新01组合就一定小于x,
于是
对于x的每一位1,对后面重新组合即可
显然最终答案不会爆maxlongint
现在想想,其实就是数位dp的思想
var c:array[..,..] of longint;
a:array[..] of longint;
n,m:longint;
procedure prepare; //预处理组合数
var i,j:longint;
begin
c[,]:=;
for i:= to do
begin
c[i,]:=;
c[i,i]:=;
for j:= to i- do
c[i,j]:=c[i-,j]+c[i-,j-];
end;
end; function count(x:longint):longint;
var p,t,i,j,q,s1,s0:longint;
begin
fillchar(a,sizeof(a),);
if x= then exit();
p:=x;
t:=;
while p<> do //十转二
begin
t:=t+;
a[t]:=p mod ;
p:=p shr ;
end;
count:=; //考虑0
for i:= to t- do //当二进制位数小于t
begin
if i mod = then q:=(i-) div + //保证0比1多
else q:=i div ;
for j:=q to i- do
count:=count+c[i-,j];
end;
s0:=;
s1:=;
for i:= to t do //先特判x是否是round number
if a[i]= then inc(s1) else inc(s0);
if s0>=s1 then count:=count+;
s0:=;
s1:=;
for i:=t- downto do
if a[i]= then
begin
for j:=i- downto do //j表示后面可能出现0的个数
if j+s0+>=i--j+s1 then //保证0比1多,i-表示当前位1后面的,+表示将这位1变成0后后面重新组合
count:=count+c[i-,j]
else break;
inc(s1); //别忘统计前面的0,个数,后面的排列情况是由起决定的
end
else inc(s0);
end;
begin
readln(n,m);
prepare;
writeln(count(m)-count(n-)); //经常用到的转化思想
end.
poj3252的更多相关文章
- [BZOJ1662][POJ3252]Round Numbers
[POJ3252]Round Numbers 试题描述 The cows, as you know, have no fingers or thumbs and thus are unable to ...
- POJ3252——Round Number(组合数学)
Round Numbers DescriptionThe cows, as you know, have no fingers or thumbs and thus are unable to pla ...
- [poj3252]Round Numbers_数位dp
Round Numbers poj3252 题目大意:求一段区间内Round Numbers的个数. 注释:如果一个数的二进制表示中0的个数不少于1的个数,我们就说这个数是Round Number.给 ...
- POJ3252 Round Numbers 【数位dp】
题目链接 POJ3252 题解 为什么每次写出数位dp都如此兴奋? 因为数位dp太苟了 因为我太弱了 设\(f[i][0|1][cnt1][cnt0]\)表示到二进制第\(i\)位,之前是否达到上界, ...
- poj3252(数位dp)(模板)
题目链接:https://vjudge.net/problem/POJ-3252 题意:求[l,r]之间的Round Number数,RN数即化为二进制后0的个数不少于1的个数的数. 思路:之前用组合 ...
- POJ3252 Round Numbers(不重复全排列)
题目问区间有多少个数字的二进制0的个数大于等于1的个数. 用数学方法求出0到n区间的合法个数,然后用类似数位DP的统计思想. 我大概是这么求的,确定前缀的0和1,然后后面就是若干个0和若干个1的不重复 ...
- poj3252 Round Numbers
Round Numbers Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 7625 Accepted: 2625 Des ...
- poj3252 组合数学
题目大意:给两个数字a,b求出[a,b]中转化成二进制后0的个数大于等于1的个数的数 例如1100转化成10-11,100-111,1000-1011,1100.保证每个区段都有1打头,然后有一段数字 ...
- poj3252(数位dp)
题目连接:http://poj.org/problem?id=3252 题意:拆成2进制,在记录0和1的个数 求区间[a,b]中,满足传化成2进制后,0的个数>=1的个数的数字的个数... 分析 ...
随机推荐
- foxtable使用笔记
1.设置关联表窗口的列的顺序:Tables("award.people").SetColVisibleWidth("name|100|sex|100|job|100|ag ...
- VLAN和Trunk
Vlan实验题: 如图所示 解答过程 (一)相同vlan之间的设备全连通 1. 在SW1和SW2上分别创建vlan2和vlan3, 命令如下 SW1# vlan database SW1(vlan)# ...
- Python学习_从文件读取数据和保存数据
运用Python中的内置函数open()与文件进行交互 在HeadFirstPython网站中下载所有文件,解压后以chapter 3中的“sketch.txt”为例: 新建IDLE会话,首先导入os ...
- 【原创】一起学C++ 之->(箭头符号) ---------C++ primer plus(第6版)
1.C++新手在指定结构成员时,不知道何时用.运算符,何时是用->运算符. 结论:如果结构标识符是结构名,则使用句点运算符:如果标识符是指向结构的指针,则使用箭头运算符. #include &l ...
- Mooncake (排序+贪心)
Mooncake is a Chinese bakery product traditionally eaten during the Mid-Autumn Festival. Many types ...
- windows 与fedora时间差
windows 默认BIOS时间当前时间UTC+时区, 按北京时间时区,就是要加8个小时. Linux默认BIOS时间是UTC时间,所以同一机子上装WINDOWS与LINUX时间上会差8个小时.这问题 ...
- XML文件序列化和反序列化的相关内容
问题缘由: XML反序列化出错,XML 文档(2, 2)中有错误,不应有 <configuration xmlns=''> 解决方法: 其实这个是很简单的,因为一般来说都是XML文档书写错 ...
- SQL学习中(序)
从校园中走出来已经两年多了,从最初的企业建站到现在的BPM流程开发,深深的感觉到自己底子很差,因此在园子里记录一下学过的知识,以此自勉. 废话到此结束,今天就先来看一下CREATE CHEMA 语句. ...
- Python之print语句
print语句可以向屏幕上输出指定的文字.比如输出'hello, world',用代码实现如下: >>> print 'hello, world' 注意: 1.当我们在Python交 ...
- C# - Generic
定义泛型类 创建泛型类,在类定义中包含尖括号语法 class MyGenericClass<T> { ... } T可以是任意标识符,只要遵循通常的C#命名规则即可.泛型类可以在其定义中包 ...