Description

小Z在玩一个叫做《淘金者》的游戏。游戏的世界是一个二维坐标。X轴、Y轴坐标范围均为1..N。初始的时候,所有的整数坐标点上均有一块金子,共N*N块。
    一阵风吹过,金子的位置发生了一些变化。细心的小Z发现,初始在(i,j)坐标处的金子会变到(f(i),fIj))坐标处。其中f(x)表示x各位数字的乘积,例如f(99)=81,f(12)=2,f(10)=0。如果金子变化后的坐标不在1..N的范围内,我们认为这块金子已经被移出游戏。同时可以发现,对于变化之后的游戏局面,某些坐标上的金子数量可能不止一块,而另外一些坐标上可能已经没有金子。这次变化之后,游戏将不会再对金子的位置和数量进行改变,玩家可以开始进行采集工作。
    小Z很懒,打算只进行K次采集。每次采集可以得到某一个坐标上的所有金子,采集之后,该坐标上的金子数变为0。
    现在小Z希望知道,对于变化之后的游戏局面,在采集次数为K的前提下,最多可以采集到多少块金子?
    答案可能很大,小Z希望得到对1000000007(10^9+7)取模之后的答案。

Input

共一行,包含两介正整数N,K。

Output

一个整数,表示最多可以采集到的金子数量。

Sample Input

1 2 5

Sample Output

18

HINT

N < = 10^12 ,K < = 100000

对于100%的测试数据:K < = N^2

题解:

  开始想偏了……导致整个人都是懵逼的。

  首先打个表发现,各位数字乘积不同结果大概是8000左右,然后开始乱搞。

  设$f_{i,j,k}$表示总共i位,开头数字为j,乘积排名为k的总数,转移就比较显然。

  然后枚举每个k,接下来就是基本的数位DP了,这样我们求出了某一列上每个位置的金块数量$ans_{k}$,然后画个图发现,在$(i,j)$位置上的数量为我们刚才DP出的$ans_{i}*ans_{j}$,给$ans$排个序,然后贪心即可。

代码:

  

 #define Troy 10/11/2017

 #include <bits/stdc++.h>

 using namespace std;

 typedef long long ll;

 const ll mod=1e9+;

 inline ll read(){
ll s=,k=;char ch=getchar();
while(ch<''|ch>'') ch=='-'?k=-:,ch=getchar();
while(ch>&ch<='') s=s*+(ch^),ch=getchar();
return s*k;
} const int N=1e6; ll has[N];int num,p[],tot; inline void dfs(ll x,int from,int step){
if(step>) return ;
has[++num]=x;
for(;from<;from++){
dfs(x*from,from,step+);
}
} ll f[][][],n,k,ans[];//f[i][j][k]:i位开头为j乘积为k的答案 inline void init(){
has[++num]=;
dfs(,,);
sort(has+,has+num+);
num=unique(has+,has+num+)-has-;// printf("num=%d\n",num);
for(int i=;i<=;i++)
f[][i][lower_bound(has+,has+num+,i)-has]=;
for(int i=;i<=;i++){
for(int j=;j<;j++){
for(int k=;k<;k++)
for(int l=;l<=num;l++){
if(f[i-][k][l]==) continue;
int x;
if(has[l]*j<=has[num]){
x=lower_bound(has+,has+num+,has[l]*j)-has;
f[i][j][x]+=f[i-][k][l];
}
}
}
}
do{
p[++tot]=n%;
n/=;
}while(n);
} inline ll calc(int pos){
ll ret=;
for(int i=;i<tot;i++){
for(int j=;j<=;j++){
ret+=f[i][j][pos];
}
}
ll last=;
for(int i=tot;i;i--){
if(last>has[pos]||last==||has[pos]%last!=) break;
for(int j=;j<p[i];j++){
int x=lower_bound(has+,has++num,has[pos]/last)-has;
ret+=f[i][j][x];
}
last*=p[i];
}
return ret%mod;
} bool vis[][]; struct node {
int pos[];ll val;
friend bool operator <(node a,node b){
return a.val!=b.val?a.val<b.val:a.pos[]!=b.pos[]?a.pos[]>b.pos[]:a.pos[]>b.pos[];
}
}; priority_queue<node> q; int main(){
n=read(),k=read();
n++;
init();
for(int i=;i<=num;i++)
ans[i]=calc(i);
sort(ans+,ans+num+);
q.push((node){num,num,ans[num]*ans[num]});
ll ret=;
while(k&&(!q.empty())){
k--;
node now;
do{
now=q.top();q.pop();
}while(vis[now.pos[]][now.pos[]]&&(!q.empty()));
if(!vis[now.pos[]][now.pos[]]){
ret+=now.val;
ret%=mod;
if(now.pos[]>)
q.push((node){now.pos[]-,now.pos[],ans[now.pos[]-]*ans[now.pos[]]});
if(now.pos[]>)
q.push((node){now.pos[],now.pos[]-,ans[now.pos[]]*ans[now.pos[]-]});
}
vis[now.pos[]][now.pos[]]=true;
}
printf("%lld\n",ret);
}

【bzoj 3131】[Sdoi2013]淘金的更多相关文章

  1. Bzoj 3131 [Sdoi2013]淘金 题解

    3131: [Sdoi2013]淘金 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 733  Solved: 363[Submit][Status][ ...

  2. bzoj 3131: [Sdoi2013]淘金

    #include<cstdio> #include<iostream> #include<queue> #include<algorithm> #def ...

  3. bzoj 3131 [Sdoi2013]淘金(数位DP+优先队列)

    Description 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1..N.初始的时候,所有的整数坐标点上均有一块金子,共N*N块.    一阵风吹 ...

  4. BZOJ 3131 [SDOI2013]淘金 - 数位DP

    传送门 Solution 这道数位$DP$看的我很懵逼啊... 首先我们肯定要先预处理出 $12$位乘起来的所有的可能情况, 记录入数组 $b$, 发现个数并不多, 仅$1e4$不到. 然后我们考虑算 ...

  5. bzoj 3131 [Sdoi2013]淘金(数位dp)

    题目描述 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1..N.初始的时候,所有的整数坐标点上均有一块金子,共N*N块. 一阵风吹过,金子的位置发生了 ...

  6. [Bzoj3131][Sdoi2013]淘金(数位dp)(优先队列)

    3131: [Sdoi2013]淘金 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 847  Solved: 423[Submit][Status][ ...

  7. [BZOJ3131] [Sdoi2013]淘金

    [BZOJ3131] [Sdoi2013]淘金 Description 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1..N.初始的时候,所有的整数坐 ...

  8. 题解-SDOI2013 淘金

    题面 SDOI2013 淘金 有一个 \(X\).\(Y\) 轴坐标范围为 \(1\sim n\) 的范围的方阵,每个点上有块黄金.一阵风来 \((x,y)\) 上的黄金到了 \((f(x),f(y) ...

  9. bzoj千题计划268:bzoj3131: [Sdoi2013]淘金

    http://www.lydsy.com/JudgeOnline/problem.php?id=3131 如果已知 s[i]=j 表示有j个<=n数的数码乘积=i 那么就会有 s[a1]*s[a ...

随机推荐

  1. CSS基础:替换元素和非替换元素

    简介 根据 "外在盒子" 是内联还是块级我们可以把元素分为内联元素和块级元素,而根据是否具有可替换内容,我们也可以把元素分为替换元素和非替换元素.这种通过修改某个属性值,例如 &l ...

  2. access窗体主体居中

    Private Sub Form_Load()DoCmd.Echo False Dim x, y As IntegerDoCmd.Maximizex = Me.WindowWidthy = Me.Wi ...

  3. Day5_模块与包(import)(form......import....)

    一个文件中定义了很多模块,然后可以再别的文件中调用这几个模块. #导入模块(import) #1,执行源文件 #2,产生以源文件为基础的全局名称空间.

  4. Open Source BI Platform List

    资源入口: awesome-business-intelligence https://github.com/thenaturalist/awesome-business-intelligence h ...

  5. 我的AngularJS学习轨迹

    开始接触Anguljar可能是在2013年初,那个时候的版本1.0.*,那个时候国内主要的中文资料AngularJS学习笔记:http://zouyesheng.com/angular.html,an ...

  6. 晒stlink以及stm8“开发板”

    先上图:( ̄▽ ̄)" 单层板+几根飞线,之前做jlink-ob做过孔整怕了,画pcb的时候尽量朝单层画的 外壳用sw建模,并3d打印 引出了swim for stm8单总线调试接口 以及sw ...

  7. 服务器禁止ping

    禁止ping后,不让别人通过域名ping到你的ip, 如果禁用后,你在ping自己的域名会给你返回服务商的IP并提示超时, 这样你就可以减少IP暴露,增加一点安全. 禁止方法: 编辑 /etc/sys ...

  8. Sublime中文编码问题

    1. 改配置 Preferences->Settings  三个全部加上 "default_encoding": "UTF-8" 2. 代码编写 2.1 ...

  9. Spring Boot实战笔记(一)-- Spring简介

    一.Spring 概述 Spring框架是一个轻量级的企业级开发的一站式解决方案.所谓的解决方案就是可以基于Spring解决所有的Java EE开发的所有问题. Spring框架主要提供了Ioc(In ...

  10. 关于input的一些问题解决方法分享

    前言 input是我们接受来自用户的数据常用标签,在前端开发中,相信每个人都会用到这个标签,所以在开发过程中也时候也会遇到一些问题,本文的内容是我在跟input相爱相杀过程中产生的,在此记录分享一下. ...