http://www.lydsy.com/JudgeOnline/problem.php?id=3131

如果已知 s[i]=j 表示有j个<=n数的数码乘积=i

那么就会有 s[a1]*s[a2] 个数 在一阵风之后到(a1,a2)位置

把所有的j用一个数组b存起来,从大到小排序
开始把(1,1)存入堆,表示当前最多的是b[1]*b[1]
每次取出堆顶(i,j),累加 b[i]*b[j],存入(i+1,j),(i,j+1),map 判重

就可以解决前k大之和的问题

i的上限是n,存不下,怎么办

我们发现 n以内 有大量的i 是无用的

只有质因数分解之后 质因子为2、3、5、7 的i 才是合法状态

所以 dp[len][0/1][c2][c3][c5][c7] 表示前len位,是否卡上界,当前i=2^c2 * 3^c3 * 5^c5 * 7^c7 的 j是多少

数位dp

注意不能放0,但是可以有前导0,所以除了最高位,都要加上前导0的贡献,即dp[][0][0][0][0][0]++ (前导0不卡上界)

#include<map>
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm> using namespace std; typedef long long LL; const int mod=1e9+; LL dp[][][][][][];
int f[][]; int a[]; int cnt;
LL b[]; priority_queue< pair<LL,pair<int,int> > >q;
map<pair<int,int>,bool>vis; void pre()
{
f[][]=;
f[][]=;
f[][]=;
f[][]=;
f[][]=;
f[][]=;
f[][]=;
f[][]=;
f[][]=;
} void reverse(int len)
{
int k=len/;
for(int i=;i<=k;++i) swap(a[i],a[len-i+]);
} void ADD(int &x,int y)
{
x+=y;
x-=x>=mod ? mod : ;
} LL Pow(LL a,int b)
{
LL res=;
for(;b;a*=a,b>>=)
if(b&) res*=a;
return res;
} void numberDP(LL n)
{
int len=;
LL m=n;
while(m) a[++len]=m%,m/=;
reverse(len);
int up,J;
int now=,nxt=;
for(int i=;i<len;++i,swap(now,nxt))
{
if(!i) dp[now][][][][][]++;
else dp[now][][][][][]++;
memset(dp[nxt],,sizeof(dp[nxt]));
for(int j=;j<=;++j)
for(int c2=;c2<=;++c2)
for(int c3=;c3<=;++c3)
for(int c5=;c5<=;++c5)
for(int c7=;c7<=;++c7)
if(dp[now][j][c2][c3][c5][c7])
{
if(j) up=a[i+];
else up=;
for(int k=;k<=up;++k)
{
J=(j && k==up);
dp[nxt][J][c2+f[k][]][c3+f[k][]][c5+f[k][]][c7+f[k][]]+=dp[now][j][c2][c3][c5][c7];
}
}
}
LL sum,tmp;
for(int c2=;c2<=;++c2)
{
tmp=Pow(,c2);
if(tmp>n) break;
for(int c3=;c3<=;++c3)
{
tmp=Pow(,c2)*Pow(,c3);
if(tmp>n) break;
for(int c5=;c5<=;++c5)
{
tmp=Pow(,c2)*Pow(,c3)*Pow(,c5);
if(tmp>n) break;
for(int c7=;c7<=;++c7)
{
tmp=Pow(,c2)*Pow(,c3)*Pow(,c5)*Pow(,c7);
if(tmp>n) break;
sum=dp[now][][c2][c3][c5][c7]+dp[now][][c2][c3][c5][c7];
if(sum) b[++cnt]=sum;/*,printf("%d %d %d %d %I64d\n",c2,c3,c5,c7,sum)*/;
}
}
}
}
} void get_kth(int k)
{
sort(b+,b+cnt+,greater<int>());
int i=,j=;
int ans=;
pair<LL,pair<int,int> >pr;
int x,y;
q.push(make_pair(b[]*b[],make_pair(,)));
while(k-- && !q.empty())
{
pr=q.top();
q.pop();
if(!pr.first) break;
ADD(ans,pr.first%mod);
x=pr.second.first;
y=pr.second.second;
if(!vis[make_pair(x+,y)])
{
q.push(make_pair(b[x+]*b[y],make_pair(x+,y)));
vis[make_pair(x+,y)]=true;
}
if(!vis[make_pair(x,y+)])
{
q.push(make_pair(b[x]*b[y+],make_pair(x,y+)));
vis[make_pair(x,y+)]=true;
}
}
printf("%d",ans);
} int main()
{
//freopen("gold.in","r",stdin);
//freopen("gold.out","w",stdout);
LL n; int k;
scanf("%lld%d",&n,&k);
pre();
numberDP(n);
get_kth(k);
return ;
}

bzoj千题计划268:bzoj3131: [Sdoi2013]淘金的更多相关文章

  1. bzoj千题计划300:bzoj4823: [Cqoi2017]老C的方块

    http://www.lydsy.com/JudgeOnline/problem.php?id=4823 讨厌的形状就是四联通图 且左右各连一个方块 那么破坏所有满足条件的四联通就好了 按上图方式染色 ...

  2. bzoj千题计划267:bzoj3129: [Sdoi2013]方程

    http://www.lydsy.com/JudgeOnline/problem.php?id=3129 如果没有Ai的限制,就是隔板法,C(m-1,n-1) >=Ai 的限制:m减去Ai &l ...

  3. bzoj千题计划134:bzoj3124: [Sdoi2013]直径

    http://www.lydsy.com/JudgeOnline/problem.php?id=3124 第一问: dfs1.dfs2 dfs2中记录dis[i]表示点i距离最长链左端点的距离 第二问 ...

  4. bzoj千题计划133:bzoj3130: [Sdoi2013]费用流

    http://www.lydsy.com/JudgeOnline/problem.php?id=3130 第一问就是个最大流 第二问: Bob希望总费用尽量大,那肯定是把所有的花费加到流量最大的那一条 ...

  5. bzoj千题计划259:bzoj3122: [Sdoi2013]随机数生成器

    http://www.lydsy.com/JudgeOnline/problem.php?id=3122 等比数列求和公式+BSGS #include<map> #include<c ...

  6. bzoj千题计划258:bzoj3123: [Sdoi2013]森林

    http://www.lydsy.com/JudgeOnline/problem.php?id=3123 启发式合并主席树 #include<cmath> #include<cstd ...

  7. bzoj千题计划196:bzoj4826: [Hnoi2017]影魔

    http://www.lydsy.com/JudgeOnline/problem.php?id=4826 吐槽一下bzoj这道题的排版是真丑... 我还是粘洛谷的题面吧... 提供p1的攻击力:i,j ...

  8. bzoj千题计划280:bzoj4592: [Shoi2015]脑洞治疗仪

    http://www.lydsy.com/JudgeOnline/problem.php?id=4592 注意操作1 先挖再补,就是补的范围可以包含挖的范围 SHOI2015 的题 略水啊(逃) #i ...

  9. bzoj千题计划177:bzoj1858: [Scoi2010]序列操作

    http://www.lydsy.com/JudgeOnline/problem.php?id=1858 2018 自己写的第1题,一遍过 ^_^ 元旦快乐 #include<cstdio> ...

随机推荐

  1. Asp.Net_序列化、反序列化

    .net序列化及反序列化 在我们深入探讨C#序列化和反序列化之前我们先要明白什么是序列化,它又称串行化,是.NET运行时环境用来支持用户定义类型的流化的机制.序列化就是把一个对象保存到一个文件或数据库 ...

  2. linux chroot 命令

    chroot,即 change root directory (更改 root 目录).在 linux 系统中,系统默认的目录结构都是以 /,即以根 (root) 开始的.而在使用 chroot 之后 ...

  3. 利用matlab写一个简单的拉普拉斯变换提取图像边缘

    可以证明,最简单的各向同性微分算子是拉普拉斯算子.一个二维图像函数 f(x,y) 的拉普拉斯算子定义为 ​ 其中,在 x 方向可近似为 ​ 同理,在 y 方向上可近似为 ​ 于是 我们得到满足以上三个 ...

  4. React笔记-事件注册

    事件机制 本系列以React v16.8.3为基础进行源码分析 React事件主要分为两部分: 事件注册与事件分发.下面先从事件注册说起. 事件注册 假设我们的程序如下: <!DOCTYPE h ...

  5. Flink standalone模式作业执行流程

    宏观流程如下图: client端 生成StreamGraph env.addSource(new SocketTextStreamFunction(...)) .flatMap(new FlatMap ...

  6. ubuntu 下配置 开发环境

    1. apache: sudo apt-get install apache2 安装好输入网址测试所否成功: http://localhost 2. mongo 已经安装好了 版本:2.4.8 ref ...

  7. PAT甲题题解-1003. Emergency (25)-最短路径+路径数目

    给出n个城市,m条边,起始点c1和目的点c2接下来给出n个城市的队伍数以及m条双向边问你求c1到c2的所有最短路径数目,以及其中经过的最多队伍数 先最短路dijkstra,同时建立vector数组pr ...

  8. 20135202闫佳歆--week6 进程的描述与创建--学习笔记

    此为个人学习笔记存档! week 6 进程的描述与创建 一.进程的描述 1.进程控制块task_struct 以下内容来自视频课件,存档在此. 为了管理进程,内核必须对每个进程进行清晰的描述,进程描述 ...

  9. Scapy安装以及简单使用

    Scapy安装以及简单使用 参考文档 scapy官方文档 前言 scapy是一个可以模拟发送报文的python程序,使用了它从此发包不愁. 安装 1.首先得安装Python2.7 ​ 在linux系统 ...

  10. KindEditor:Ajax提交表单时获取不到HTML内容

    当用Ajax提交表单时,KindEditor的内容获取不到,HTML数据获取不了 原因:当ajax提交时,KindEdito的HTML数据还没有同步到表单中来,那怎么去获取HTML数据呢? ----- ...