CSP模拟赛 number (二分+数位DP)
2024-08-27 04:05:49
题面
给定整数m,km,km,k,求出最小和最大的正整数 nnn 使得 n+1,n+2,…,2nn+1,n+2,…,2nn+1,n+2,…,2n 中恰好有 mmm 个数 在二进制下恰好有 kkk 个 111。如果有无数个满足条件则输出一行一个整数−1-1−1。有TTT组数据。
T≤2000T\le 2000T≤2000
m≤1e18m\le 1e18m≤1e18
k≤64k\le 64k≤64
保证1e181e181e18内 存在一个数满足条件。
题解
设f(i)f(i)f(i)表示i+1,i+2,...,2ii+1,i+2,...,2ii+1,i+2,...,2i中在二进制下为恰好有kkk个111的数的个数。可以证明打表发现f(i)f(i)f(i)是单调不降的。所以就可以二分了。二分后数位DPDPDP就行了。计算f(i)f(i)f(i)可以用g(2i)−g(i)g(2i)-g(i)g(2i)−g(i),其中g(i)g(i)g(i)表示111到iii的数中在二进制下恰好有kkk个111的数的个数。
因为数位DPDPDP的数组是可以多次用的,所以时间复杂度是整体两个logloglog的,而每次时间复杂度为O(+Tlog2(二分上界))O(+T\log^2(二分上界))O(+Tlog2(二分上界))
但是这里的二分上界并不是1e181e181e18,因为保证最小的nnn在1e181e181e18内,但是最大的可能超出。所以上界我设的2632^{63}263
输出−1-1−1的情况只有一种就是k=1k=1k=1,在n=2pn=2^pn=2p时满足。
CODE
#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
ULL m, f[70][70];
int k, c[70], n;
bool vis[70][70];
ULL dfs(int i, int j, bool fp) {
if(!fp && vis[i][j]) return f[i][j];
if(i == 0) return j == 0;
ULL ans = 0; int mx = fp ? c[i] : 1;
for(int d = 0; d <= mx; ++d) ans += dfs(i-1, j-d, fp&&d==mx);
if(!fp) vis[i][j] = 1, f[i][j] = ans;
return ans;
}
ULL cal(ULL x) {
for(n=0; x; c[++n]=x&1,x>>=1);
return dfs(n, k, 1);
}
ULL chk(ULL x) { return cal(2*x) - cal(x); }
int main() {
int T; scanf("%d", &T); while(T--) {
scanf("%llu%d", &m, &k);
if(k == 1) puts("-1");
else {
ULL l = 1, r = 1llu<<63, mid;
while(l < r) {
mid = (l + r) >> 1;
if(chk(mid) >= m) r = mid;
else l = mid+1;
}
ULL L = 1, R = 1llu<<63, MID;
while(L < R) {
MID = (L + R) >> 1;
if(chk(MID) > m) R = MID;
else L = MID+1;
}
printf("%llu %llu\n", l, L-1);
}
}
}
最新文章
- Sort merge join、Nested loops、Hash join(三种连接类型)
- MINA系列学习-IoAccpetor
- 一个简单的猜大小的小游戏 python
- [POJ3096]Surprising Strings
- 从原理上理解NodeJS的适用场景
- Reveal UI 分析工具分析手机 App
- 《构建之法》第8、9、10章读书笔记、读后感以及Sprint1总结
- 数组和集合List的相互转化
- Delphi ComboBox的属性和事件、及几个鼠标事件的触发
- Asp.net缓存技术(HttpRuntime.Cache)
- Java多线程3:Thread中的实例方法
- Spark记录-SparkSQL一些操作
- python - class类 (二) 静态属性/类方法/静态方法
- Java发送邮件时标题和发件人乱码
- BZOJ1071 [SCOI2007]压缩 其他
- :命令模式:Command
- IOS 通过脚本自动打包工具 webfrogs/xcode_shell
- MyEclipse关闭当前正在编辑的页面
- vi的复制粘贴命令 -- (转)
- 【图片下载-代码】java下载网络图片资源例子