UPC 2223: A-Number and B-Number(数位DP+二分)
积累点:
1: (l&r)+((l^r)>>) == (l+r)/2
2: 注意判断现在是否有限制。当枚举下一个量时,是(isQuery && j==end),不要搞错。
传送门:http://acm.upc.edu.cn/problem.php?id=2223
题意:
能被7整除或者含7的数称为A-Number,所有A-Number从小到大写好,下标编号(从1开始),去掉那些下标为A-Number的数,剩下的数称为B-Number。求第N个B-Number是多少。
思路:
求A-Number就是简单的数位DP。
dp[i][mod] 表示所有i位数中,%7==mod 的数的个数
dp[i][mod] = (j != 7) dp[i-1][(mod-(j*10i-1)%7+7)%7]
(j == 7) 10i-1(nowx%10i-1+1)
(j=0~9(end))
之后 二分答案就行了。[0~B]包含 cal(B) - cal(cal(B)) 个B-Number。(B包含的ANumber的数目,就是下标最大。这么大的下标范围内有多少ANumber,减掉,剩下就是BNumber的数量)
二分的时候注意二分到最小的那个。就是说。二分的可能是这样
7 7 7 8 8 8
如果查的是8, 则这时候应该二分到第一个8那个位置。
代码:
#include <cstdio>
#include <cstring> long long dp[][];
int num[];
long long nowx; long long dfs(int i, int mod, bool isQuery) {
if (i == ) {
return mod == ;
}
long long &nowdp = dp[i][mod];
if (!isQuery && ~nowdp) {
return nowdp;
}
int end = isQuery?num[i]:;
long long ans = ;
long long ten = ;
for (int k = ; k < i-; k++) ten *= ; for (int j = ; j <= end; j++) {
if (j == ) {
ans += (isQuery&&j==end)?((nowx%ten)+):ten; // 这一句要小心。
} else {
ans += dfs(i-, (mod-(j*ten)%+)%, isQuery && j == end);
}
}
if (!isQuery) nowdp = ans;
return ans;
} long long cal(long long x) {
nowx = x;
int len = ;
if (x == ) return ;
while (x) {
num[++len] = x%;
x/=;
}
return dfs(len, , true)-; // 减掉0
} long long solve(long long number) {
long long l = ;
long long r = 10e19;
while (l<r) {
long long mid = (l&r)+((l^r)>>);
long long Anum = cal(mid);
long long Bnum = Anum - cal(Anum);
if (Bnum >= number) r = mid;
else l = mid+;
}
return l;
}
int main(){
long long n;
memset(dp, -, sizeof(dp));
while (scanf("%lld", &n) != EOF) {
printf("%lld\n", solve(n));
}
}
UPC 2223: A-Number and B-Number(数位DP+二分)的更多相关文章
- poj3208 Apocalypse Someday 数位dp+二分 求第K(K <= 5*107)个有连续3个6的数。
/** 题目:poj3208 Apocalypse Someday 链接:http://poj.org/problem?id=3208 题意:求第K(K <= 5*107)个有连续3个6的数. ...
- CodeChef FAVNUM FavouriteNumbers(AC自动机+数位dp+二分答案)
All submissions for this problem are available. Chef likes numbers and number theory, we all know th ...
- HDU 3943 数位dp+二分
K-th Nya Number Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 125536/65536 K (Java/Others) ...
- hihocoder #1301 : 筑地市场 数位dp+二分
题目链接: http://hihocoder.com/problemset/problem/1301?sid=804672 题解: 二分答案,每次判断用数位dp做. #include<iostr ...
- hdu 3709 Balanced Number(平衡数)--数位dp
Balanced Number Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65535/65535 K (Java/Others) ...
- C - Balanced Number HDU - 3709 (数位dp)
题目链接:https://cn.vjudge.net/contest/278036#problem/C 题目大意:手首先是T组数据,然后每一次输入两个数l,r,求这个区间里面满足以某个数字为中心的两侧 ...
- hdu 3271 SNIBB 数位DP+二分
思路:dp[i][j]:表示第i位在B进制下数字和. 用二分找第k个数! 代码如下: #include<iostream> #include<stdio.h> #include ...
- HDU 3271 数位dp+二分
SNIBB Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submi ...
- [uva 1350]数位dp+二分
题目链接:https://vjudge.net/problem/38405 #include<bits/stdc++.h> using namespace std; ][]; ]; lon ...
随机推荐
- Jenkins注意点
这里要填写 在 Linux 上 生成的 git 私钥 并且带上 前后 注释 ------start ----- ---end -------
- 局域网映射到公网-natapp实现
在开发时可能会有这样的需求: 需要将自己开发的机器上的应用提供到公网上进行访问,但是并不想通过注册域名.搭建服务器等等一系列繁琐的操作来实现. 例如:微信公众号的开发调试就需要用到域名访问本机项目. ...
- 下载旧版本的JDK
下载旧版本的JDK 有的时候我们需要去下载旧版本的JDK,但是进入Oracle官网,显示的总是新版的JDK,这里告诉大家怎么样去下载旧版本的JDK. 首先去JavaSE的 下载界面 拉到最下面,找到这 ...
- jvm架构以及Tomcat优化
JVM栈 JVM栈是线程私有的,每个线程创建的同时都会创建JVM栈,JVM栈中存放的为当前线程中局部基本类型的变量(java中定义的八种基本类型:boolean.char.byte.short.i ...
- F查询与Q查询
F查询 如果我们要对两个字段的值做比较,那该怎么做呢? Django 提供 F() 来做这样的比较.F() 的实例可以在查询中引用字段,来比较同一个 model 实例中两个不同字段的值. # 查询评论 ...
- 【南邮】md5 collision write up
源码: <?php $md51 = md5('QNKCDZO'); $a = @$_GET['a']; $md52 = @md5($a); if(isset($a)){ if ($a != 'Q ...
- python基础学习笔记——循环语句(while、for)
while 循环 流程控制语句 while 1.基本循环 while 条件: # 循环体 # 如果条件为真,那么循环则执行 # 如果条件为假,那么循环不执行 2.break break 用于退出当 ...
- python画图axis和axes以及subplot的区别
https://www.zhihu.com/question/51745620 axis顾名思义就是轴. axes简单说来就是灵活的子图.
- 关于dispatch_sync死锁问题
首先,我们来看下下面一个例子: 代码:(串行队列里同步线程嵌套) NSLog(@"haha"); dispatch_queue_t queue = dispatch ...
- ogre3D学习基础6---场景管理器的使用
场景管理器的使用 最常使用的坐标系统空间(同时也是Ogre程序所能提供的)即是世界空间(World).父节点空间(Parent)以及本地空间(Local). 1.世界空间 就是物体所存在的地方,当我们 ...