积累点:

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+二分)的更多相关文章

  1. 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的数. ...

  2. CodeChef FAVNUM FavouriteNumbers(AC自动机+数位dp+二分答案)

    All submissions for this problem are available. Chef likes numbers and number theory, we all know th ...

  3. HDU 3943 数位dp+二分

    K-th Nya Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 125536/65536 K (Java/Others) ...

  4. hihocoder #1301 : 筑地市场 数位dp+二分

    题目链接: http://hihocoder.com/problemset/problem/1301?sid=804672 题解: 二分答案,每次判断用数位dp做. #include<iostr ...

  5. hdu 3709 Balanced Number(平衡数)--数位dp

    Balanced Number Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others) ...

  6. C - Balanced Number HDU - 3709 (数位dp)

    题目链接:https://cn.vjudge.net/contest/278036#problem/C 题目大意:手首先是T组数据,然后每一次输入两个数l,r,求这个区间里面满足以某个数字为中心的两侧 ...

  7. hdu 3271 SNIBB 数位DP+二分

    思路:dp[i][j]:表示第i位在B进制下数字和. 用二分找第k个数! 代码如下: #include<iostream> #include<stdio.h> #include ...

  8. HDU 3271 数位dp+二分

    SNIBB Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submi ...

  9. [uva 1350]数位dp+二分

    题目链接:https://vjudge.net/problem/38405 #include<bits/stdc++.h> using namespace std; ][]; ]; lon ...

随机推荐

  1. C++ string头文件

    转载自https://blog.csdn.net/superna666/article/details/52809007/ 作者 zhenzhenjiajia888 标准c++中string类函数介绍 ...

  2. 看了下opengl相关的资料,踩了一个坑,记录一下

    2019/03/10 下午看了下关于opengl的资料,然后把敲了下代码,然后程序报错了.代码如下: #include <glad/glad.h> #include <GLFW/gl ...

  3. C#基础-数组-ArrayList

    数组ArrayList using System.Collections; //表示引入集合的命名空间 数组ArrayList容量本身是不固定的,根据存储的数据动态变化 // 声明一个ArrayLis ...

  4. phpExcel使用方法二

    require_once './phpexcel/PHPExcel.php'; // 首先创建一个新的对象 PHPExcel object $objPHPExcel = new PHPExcel(); ...

  5. 实验4 —— [bx]和loop的使用

    实验 综合使用 loop.[bx],编写完整汇编程序,实现向内存 b800:07b8 开始的连续 16 个字单元重复填充字数据 0403H. 以下为示例程序: assume cs:code # 1 c ...

  6. CodeForces - 485D Maximum Value (数学)

    题意: n个数,求出这些数中满足 ai >= aj 的 ai % aj 的最大值. 排序去重,然后对于每一个a[i], 如果找到a[i] 的一个倍数 k*a[i] (k > 1)的位置,那 ...

  7. Python之code对象与pyc文件(二)

    上一节:Python之code对象与pyc文件(一) 创建pyc文件的具体过程 前面我们提到,Python在通过import或from xxx import xxx时会对module进行动态加载,如果 ...

  8. mysql中的存储引擎

    MySQL中常用的几种存储引擎:innoDB.bdb.myisam.memory以及这几个引擎的讲解: InnoDB存储引擎: (1) innodb存储引擎该mysql表提供了事务,回滚以及系统崩溃修 ...

  9. java_时间戳与Date_相互转化

    [转自:http://blog.csdn.net/heng615975867/article/details/36016617] 1.时间戳的定义 时间戳是指文件属性里的创建.修改.访问时间. 数字时 ...

  10. luogu1233 木棍加工

    先排个序然后做最长上升子序列就行了. #include <algorithm> #include <iostream> #include <cstdio> usin ...