CF261E Maxim and Calculator

题目大意:

有两个初始参数 $ a=1 $ , $ b=0 $ ,你可以对它们进行两个操作: $ b~+=1 $ 或 $ a~\times =b $ ,最终的 $ a $ 才是你所得到的数 。 现在给你三个数 $ l,r,p $ ,让你求在区间 $ [l,r] $ 内可以用不超过 $ p $ 次操作得到的数的个数。数据范围: $ (2<=l<=r<=10^{9},1<=p<=100) $



$ solution: $

很神仙的一道题,当时看了很久只能想到:每个我所得到的数,一定是若干个可能不同的 $ b $ 的乘积,。又因为 $ b $ 每次只能加1,所以我们如果要用最少的步数得到一个数 $ a $ ,最终 $ b $ 的大小一定是 $ b $ 的最大质因子!同理,最大质因子大于 $ p $ 的数一定不可通过少于 $ p $ 的次数得到

当时的想法是线性筛最大质因子,然后暴力判断,复杂度 $ O(n) $ 显然超时。然后死活没想到可以筛 $ p $ 以下质数所构成的数( $ 10^9 $ 里面不超过 $ 3\times 10^6 $ 个 )!

好吧,回归正题。根据上面我们的分析,所有最大质因子大于 $ p $ 的数一定不可通过少于 $ p $ 的次数得到,所以我们可以找出所有最大质因子在 $ p $ 以内的数。怎么求?这其实等同于求 $ p $ 以内的所有质数可以构造的数(注意题目说 $ 2\leq r $ ,所以不考虑1)(然后我们现线性筛质数,再搜索一下即可)。然后我们发现这样的数不超过 $ 3\times 10^6 $ 个,我们用一个数组 $ a[] $ 存起来。于是我们考虑怎么判断 $ a[] $ 里面的数是否能在 $ p $ 次操作内得到。

首先我们要明白一个点:所有 $ a[] $ 里的数都可以通过 $ a[] $ 里比它小的数构造出来。证明:对于 $ a[] $ 里的数 $ i $ ,如果它的最大质因子为 $ k $ ,那么 $ i/k $ 一定在 $ a[] $ 中,因为 $ i/k $ 的所有质因子都小于 $ p $ 。于是我们考虑 $ f[i][j] $ 表示 $ b $ 的大小为 $ i $ 时 $ j $ 的最小构造步数。我们从小到达枚举 $ b $ ,每个 $ b $ 可以选用很多次,这不就是一个完全背包吗?不过是 $ b $ 要被乘上去而已!注意我们的 $ a[] $ 数组是离散化的,我们先排一遍序,然后用单调队列找到 $ a[k]=a[j]*i $ 即可做到 $ O(1) $ 转移!

$ f[i][k]=f[i][j]+1 \quad (~a[j]\times i=a[k]~) $

复杂度: $ O(p\times 3 \times 10^6) $ ,很勉强



$ code: $

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set> #define ll long long
#define db double
#define rg register int using namespace std; int l,r,p,n; // n表示a数组的大小
int ans,tt; // tt素数个数
int a[3000005]; //最大质因子小于p的数的集合
int f[3000005]; //构造a[i]这个数的最少步数
bool d[3000005]; //是否已经加入贡献
int pr[505]; //素数表
bool vis[505]; //筛素数 inline int qr(){
register char ch; register bool sign=0; rg res=0;
while(!isdigit(ch=getchar()))if(ch=='-')sign=1;
while(isdigit(ch))res=res*10+(ch^48),ch=getchar();
if(sign)return -res; else return res;
} inline void prime(int x){ //线性筛素数
for(rg i=2;i<=x;++i){
if(!vis[i])pr[++tt]=i;
for(rg j=1;j<=tt;++j){
if(i*pr[j]>x)break;
vis[i*pr[j]]=1;
if(!(i%pr[j]))break;
}
}
} //找到最大质因子小于p的数
//等效于我们构造小于p的质数所能构造的数
inline void dfs(int i,ll v){ //i是当前轮到的质数
if(i>tt)return ;
dfs(i+1,v); //不用这个质数
while(1){
v*=pr[i]; //不断选用这个质数
if(v>r)return ; //退出
dfs(i+1,v);
a[++n]=v; //记录这个数
}
} int main(){
l=qr(); r=qr(); p=qr();
prime(p); dfs(1,1); a[++n]=1; //预处理
sort(a+1,a+n+1); f[1]=0;
for(rg i=2;i<=n;++i) f[i]=101; //赋初值无穷大
for(rg i=2;i<=p;++i){
for(rg j=1,k=1;j<=n;++j){
while(k<=n&&a[j]*i>a[k])++k; //因为a数组离散化,所以单调队列查找
if(k>n)break; if(a[j]*i!=a[k])continue;
f[k]=min(f[k],f[j]+1); //更新步数
if(d[k]||f[k]+i>p||a[k]<l)continue; //注意第二个判断
d[k]=1; ++ans; //步数在p范围内,计入答案
}
}
printf("%d\n",ans);
return 0;
}

CF261E Maxim and Calculator (质数,完全背包)的更多相关文章

  1. CF261E Maxim and Calculator

    CF261E Maxim and Calculator 洛谷评测传送门 题目描述 Maxim has got a calculator. The calculator has two integer ...

  2. [CF261E]Maxim and Calculator_搜索_欧拉筛素数_动态规划

    Maxim and Calculator 题目链接:https://www.luogu.org/problem/CF261E 数据范围:略. 题解: 考试的时候只会暴力,学弟太强了$\%\%\% Or ...

  3. Codeforce 水题报告

    最近做了好多CF的题的说,很多cf的题都很有启发性觉得很有必要总结一下,再加上上次写题解因为太简单被老师骂了,所以这次决定总结一下,也发表一下停课一星期的感想= = Codeforces 261E M ...

  4. 考前停课集训 Day2 非

    因为太长了 所以一天一天分开发 Day2 昨天晚上没开黑车 没脱衣服就睡了 可能是我难受了…… 新的一天. 早上好. 我没去晨跑,早上先和团长集合了,没看见rkbudlo来 于是就先吃饭了 去机房的时 ...

  5. HGOI 20190519 题解

    脑补了一下今天的比赛难度和之前zju-lzw出的题目画风迥异. 难度完全不是一个水平的好伐. Probem A palindrome 给出一个$n$个元素的数组,可以任意指定一个数字$m$让所有$a_ ...

  6. Codeforces 922 思维贪心 变种背包DP 质因数质数结论

    A #include <bits/stdc++.h> #define PI acos(-1.0) #define mem(a,b) memset((a),b,sizeof(a)) #def ...

  7. BZOJ 1004: [HNOI2008]Cards( 置换群 + burnside引理 + 背包dp + 乘法逆元 )

    题意保证了是一个置换群. 根据burnside引理, 答案为Σc(f) / (M+1). c(f)表示置换f的不动点数, 而题目限制了颜色的数量, 所以还得满足题目, 用背包dp来计算.dp(x,i, ...

  8. BZOJ 1025: [SCOI2009]游戏( 背包dp )

    显然题目要求长度为n的置换中各个循环长度的lcm有多少种情况. 判断一个数m是否是满足题意的lcm. m = ∏ piai, 当∑piai ≤ n时是满足题意的. 最简单我们令循环长度分别为piai, ...

  9. hdu 6125 -- Free from square(状态压缩+分组背包)

    题目链接 Problem Description There is a set including all positive integers that are not more then n. Ha ...

随机推荐

  1. hdu 4511 (AC自动机)

    注意标记一个点后,fail树上的子节点都会被标记 跑spfa,dp也可以 #include<iostream> #include<cstdio> #include<str ...

  2. C# App.config 自定义 配置节

    1)App.config <?xml version="1.0" encoding="utf-8" ?><configuration>  ...

  3. springboot打war包部署tomcat服务器,以及表单提交数据乱码处理

    小白觉得springboot打成jar包直接使用内嵌的tomcat或jetty容器(java -jar xxx.jar)运行项目不利于定位问题,我还是习惯于查看tomcat或nginx的日志来定位问题 ...

  4. 有关MSSQL2000在Win7上的安装

    https://baijiahao.baidu.com/s?id=1593533837896849226&wfr=spider&for=pc 怎么在win7下安装sql server2 ...

  5. Python学习之==>线程&&进程

    一.什么是线程(thread) 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一个线程指的是进程中一个单一顺序的控制流,一个进程中可以包含多个线程,每条线程并行 ...

  6. RESR API (一)之Requests

    Requests 如果您正在做基于REST的Web服务,您应该忽略request.POST. - Malcom Tredinnick,Django开发团队 REST框架的Request类扩展了标准的H ...

  7. 记一次Python pip安装失败的总结

    pip 安装失败时,可能换此方法可解决1.升级pip版本,这个一般会主动提示python3 -m pip install --upgrade pip2.修改pip源,默认的pip源速度实在无法忍受,或 ...

  8. 【MM系列】SAP MM模块-控制采购订单中某些项目的输出显示

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[MM系列]SAP MM模块-控制采购订单中某些 ...

  9. [Python3] 004 字符串的基本使用

    目录 1. 字符串简介 1.1 作用 1.2 注意点 2. 使用方式 2.1 用引号括起来 少废话,上例子 2.2 单.双引号可以"轮换交替" 少废话,上例子 3. 转义字符 3. ...

  10. [19/06/06-星期四] HTML基础_文本标签、列表(有序、无序、定义)、文本格式化(单位、字体、大小写、文本修饰、间距、对齐文本)

    一.文本标签 em:用来表示一段内容的着重点,语气上的强调.一般显示为斜体 i:是斜体显示,和em显示效果一样.h5规定不需要着重的内容而是单纯加粗或斜体可以用i或b.用的不多 strong:用来表示 ...