题意:定义S(n) = n*各数位之积,然后给定L<=R<=10^18,求有多少个n在[L,R]区间内

思路:

看了半天无从下手。。看完题解才豁然开朗。。

具体思路看vani神博客吧。讲的很清楚。。

code:

 #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = ;
const ll Inf = 1000000000LL;
int d[maxn], dc[maxn][], tot;
int td, tc[]; void dfs(int r, int s, ll num){
if (num > Inf) return;
if (r == || s == ){
d[tot] = num;
for (int i = ; i < ; ++i)
dc[tot][i] = tc[i];
tot++;
return;
}
dfs(r + , s, num);
tc[r-]++;
dfs(r, s + , num * r);
tc[r-]--;
} ll frac[];
ll count(int m){
int left = m;
ll res = frac[m];
for (int i = ; i < ; ++i) left -= tc[i], res /= frac[tc[i]];
res /= frac[left];
return res;
} int bit[]; ll calculate(ll b, int p){
if (b <= ) return ;
int k = ;
while (b > ) bit[++k] = b % , b /= ;
int size = ;
for (int i = ; i < ; ++i)
tc[i] = dc[p][i], size += tc[i];
ll res = ;
for (int i = ; i < k; ++i)
if (i >= size) res += count(i);
for ( ;k > ; --k){
if (bit[k] == || size > k) break;
for (int i = ; i < bit[k]; ++i) if (tc[i-]){
--tc[i-], --size;
if (k > size) res += count(k - );
++tc[i-], ++size;
}
if (bit[k] >= ){
if (k > size) res += count(k-);
if (tc[bit[k]-] == ) break;
--tc[bit[k]-], --size;
}
}
return res;
} ll calculate(ll x){
if (x <= ) return ;
ll res = ;
for (int i = ; i < tot; ++i)
res += calculate(x / d[i] + , i);
return res;
} void pre_do(){
frac[] = ;
for (int i = ; i <= ; ++i) frac[i] = frac[i-] * i;
memset(tc, , sizeof(tc));
tot = ;
dfs(, , );
} int main(){
// freopen("a.in", "r", stdin);
// freopen("a.out", "w", stdout);
pre_do();
ll l, r;
while (cin >> l >> r){
ll ans = calculate(r) - calculate(l - );
cout << ans << endl;
}
return ;
}

[violet2]sillyz的更多相关文章

  1. Atitit.软件命名空间  包的命名统计 及命名表(2000个名称) 方案java package

    Atitit.软件命名空间  包的命名统计 及命名表(2000个名称) 方案java package 1. 统计的lib jar 列表1 2. Code3 3. 常用包名按找字母排序(2000个)4 ...

随机推荐

  1. How to install VCM 2 Ford IDS 109 software

    How to install Ford IDS 109: 1- Install the ids 86 before changing the date to 1 07 2015 (hold the d ...

  2. Oracle Linux下数据库操作的相关问题

    1.su - oracle 切换到oracle用户 lsnrctl status 查看数据库监听状态 lsnrctl start 打开数据库监听 2.Connected to an idle inst ...

  3. sys安装

    1.将SYS驱动文件放到系统目录的SYSTEM32目录中.2.按WIN+R组合键,在运行框中输入:regsvr32 sys所在全路径,点击确定即可.

  4. 动态加载及Servlet容器加载

    动态加载 动态加载是 Servlet 3.0 中的新特性,它可以实现在不重启 Web 应用的情况下加载新的 Web 对象(Servlet.Filter.Listener). 为了实现动态加载的第一种方 ...

  5. MySQL 检索数据及提高检索速度的方法

    检索数据 mysql> SELECT [DISTINCT] 表名.列名,表名.列名,表名.列名 -- 使用通配符*表示所有列 DISTINCT表示返回不同的值 -> FROM 数据库名.表 ...

  6. serial -1

    #include <reg52.h>#include <stdio.h>#define uchar unsigned charsbit LED = P2^2;uchar rec ...

  7. Spring IOC(八)bean 的创建

    Spring IOC(八)bean 的创建 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10198698.html) 参考: 每天用心记录一点点.内 ...

  8. 摹客iDoc201901-2新功能点评

    2019才刚刚开始,摹客团队就已经蓄势待发.马不停蹄地给大家带来了又一份惊喜.实话说,这次小摹都忍不住要点个赞!下面就赶紧带大家看看iDoc又更新了哪些新功能: 1.标注和评论融合.协作更高效 iDo ...

  9. cocos jsb工程转html 工程

    1 CCBoot.js prepare方法:注掉下面这行,先加载moduleConfig中的脚本后加载user脚本 //newJsList = newJsList.concat(jsList); // ...

  10. MMS从Contacts中添加收件人显示email账号

    android系统默认代码,MMS中可以添加email地址作为收件人,但是从Contacts中选择收件人时却不显示email. 解决思路:为了降低修改量,在原来只搜索phoneNum的基础上,再做一次 ...