CQOI2016 伪光滑数
2016-04-20 09:09
169 查看
这里讲讲搜索。
二分答案ans,若要求ans~N中伪光滑数的个数,可以用1~N的个数减去1~ans-1的个数。搜索x范围内伪光滑数的个数,先枚举伪光滑数中最大的质因子,就可以知道伪光滑数因子个数的上限,以及因数大小的上限,可以设计dfs函数dfs(num,x,last)表示伪光滑数因子个数的上限,伪光滑数大小上限,上次用过的因子。直接枚举所用的因子转移状态,其中last不递增防止计算重复。
优化就是若last^num<=x,意味着剩下的因子可以在last之内随便选,利用挡板原理那么方案数就是C(last以内因子个数,last以内因子个数+num),其中不一定要选够num个因子,所以相当于多了一个可以选的因子。可以卡过。
这个方法可以通过k为任意值的数据,N=10^18时,k最大为5百万左右,附上代码。
二分答案ans,若要求ans~N中伪光滑数的个数,可以用1~N的个数减去1~ans-1的个数。搜索x范围内伪光滑数的个数,先枚举伪光滑数中最大的质因子,就可以知道伪光滑数因子个数的上限,以及因数大小的上限,可以设计dfs函数dfs(num,x,last)表示伪光滑数因子个数的上限,伪光滑数大小上限,上次用过的因子。直接枚举所用的因子转移状态,其中last不递增防止计算重复。
优化就是若last^num<=x,意味着剩下的因子可以在last之内随便选,利用挡板原理那么方案数就是C(last以内因子个数,last以内因子个数+num),其中不一定要选够num个因子,所以相当于多了一个可以选的因子。可以卡过。
第二个优化就是当x比较小时记忆化一下,优化明显。
这个方法可以通过k为任意值的数据,N=10^18时,k最大为5百万左右,附上代码。
#include<cstdio> #include<cstring> #include<algorithm> #define fo(i,a,b) for(int i=a;i<=b;i++) #define fd(i,a,b) for(int i=a;i>=b;i--) using namespace std; typedef long long ll; ll N; ll p[200],top; const ll inf=3000000000000000000; ll lim[200][200],c[200][200]; void prepare() { fo(i,2,128) { int ok=1; fo(j,1,top) if (i%p[j]==0) ok=0; if (ok) p[++top]=i; } c[0][0]=1; fo(i,1,100) fo(j,0,i) c[j][i]=(j>0?c[j-1][i-1]:0)+c[j][i-1]; } ll f[70][3000][40]; ll dfs(ll cs,ll n,ll last) { if (n<3000 && f[cs] [last]) return f[cs] [last]; if (n==0) return 0; if (cs==0) return 1; if (lim[last][cs]<=n) return c[cs][last+cs]; ll re=1; fd(i,last,1) re+=dfs(cs-1,n/p[i],i); if (n<3000) f[cs] [last]=re; return re; } ll get(ll n) { ll re=0; fo(i,1,top) { lim[i][1]=p[i]; fo(j,2,70) { lim[i][j]=lim[i][j-1]*p[i]; if (lim[i][j]/p[i]!=lim[i][j-1]) lim[i][j]=inf; } } fo(i,1,top) { ll cs=0,tp=N; while (tp>=p[i]) cs++,tp/=p[i]; ll num=cs-1; re+=dfs(num,n/p[i],i); } return re; } int main() { prepare(); ll k; scanf("%lld%lld",&N,&k); ll l=1,r=N,srm=get(N),ans=0; while (l<=r) { ll mid=(l+r)>>1; if (srm-get(mid-1)>=k) ans=mid,l=mid+1; else r=mid-1; } printf("%lld",ans); }
相关文章推荐
- 大学毕业4年-回顾和总结(8)-全局观-互联网项目研发-不在其位亦谋其政
- 想从事分布式系统,计算,hadoop等方面,需要哪些基础,推荐哪些书籍?--转自知乎
- Linux命令累积
- HTTPS的误解(二)
- I.MX6 开启 1000Mb/s interface
- 模仿微信支付输入密码框的效果
- 记录自己的第三方接入
- Linux内核将要支持最新龙芯3A2000/3B2000
- TCP/IP 网络编程 (三)
- JS学习笔记
- poj 3459(背包问题)
- ios,使用CocoaPods做第三方库的依赖管理
- 【HNOI2016】最小公倍数
- iosGCD其一
- DIY自己的虚拟现实世界前篇
- Ubuntu Server 11.04 安装 Oracle 11g r2 图解教程
- HTTPS的误解(一)
- window 和 linux 环境下杀死tomcat进程——也可以解决其他端口被占用的问题
- HDU 1317 XYZZY
- mysql中GROUP BY结合GROUP_CONCAT的使用