3131: [Sdoi2013]淘金

Time Limit: 30 Sec  Memory Limit: 256 MB
Submit: 733  Solved: 363
[Submit][Status][Discuss]

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

  久违的的数位DP题……
  首先,我们可以发现横纵坐标没有任何关系,完全独立,所以我们真正要做的是求出每个数有多少个数以他为f值。按照套路我们还是应该先dfs一下各种可能的乘积,然后弱到一定地步的我就懵了,乘积得多少种啊,存都存不下,然后事实证明我错了,实践证明我只要打一下表就会发现其实只有八千多个乘积……
  求出来所有乘积之后我们接着按照数位DP的套路搞。不过为了方便,我们把我们得到的所有乘积先去重和离散。设f[i][j][k]为当前我们算到第i位,第i位为j,当前乘积离散后为k的方案数。转移也是很好转移的,直接枚举那一位的数是几就好了。统计答案的时候也是按照套路,先统计位数比n低的,然后将位数从高到低依次统计每一个k答案即可。至于答案。我们用优先队列排序就可以了。
 #include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <vector>
#define N 10005
using namespace std;
long long n;
int k,zz,cnt;
long long c[],p=;
long long jg[];
void dfs(long long x,int st,int len)
{
if(len==)
{
return;
}
zz++;
jg[zz]=x;
for(int i=st;i<=;i++)
{
dfs(x*i*1ll,i,len+);
}
}
long long f[][][N];
long long ans[N];
long long work(int x)
{
long long sum=;
for(int i=;i<cnt;i++)
{
for(int j=;j<=;j++)
{
sum+=f[i][j][x];
}
}
long long la=;
for(int i=cnt;i>;i--)
{
if(la==||jg[x]%la||la>jg[x])break;
int t=lower_bound(jg+,jg++zz,jg[x]/la)-jg;
for(int j=;j<c[i];j++)
{
sum+=f[i][j][t];
}
la*=c[i];
}
return sum;
}
map<int,bool> vi[N];
struct no{
int a,b;
long long data;
bool friend operator < (no a,no b)
{
return a.data<b.data;
}
};
int main()
{
scanf("%lld%d",&n,&k);
zz++;jg[zz]=;
long long tt=n;
while(tt)
{
cnt++;
c[cnt]=tt%;
tt/=;
}
c[]++;
dfs(,,); sort(jg+,jg+zz+);
zz=unique(jg+,jg+zz+)-jg-;
for(int i=;i<=;i++)
{
f[][i][lower_bound(jg+,jg+zz+,i)-jg]=;
}
for(int i=;i<cnt;i++)
{
for(int j=;j<=;j++)
{
for(int k=;k<=;k++)
{
for(int l=;l<=zz;l++)
{
if(!f[i][j][l])continue;
if(jg[l]*(long long)k>jg[zz])continue;
f[i+][k][lower_bound(jg+,jg++zz,jg[l]*k)-jg]+=f[i][j][l];
}
}
}
}
for(int i=;i<=zz;i++)
{
ans[i]=work(i);
}
sort(ans+,ans+zz+); no aa;
aa.a=aa.b=zz;
aa.data=ans[zz]*ans[zz];
priority_queue<no> q1; q1.push(aa);
long long sum=;
while(k&&!q1.empty())
{
k--;
while(!q1.empty()&&vi[q1.top().a][q1.top().b]) q1.pop();
aa=q1.top();q1.pop();
sum+=aa.data%p;
sum%=p;
vi[aa.a][aa.b]=;
aa.a--;
aa.data=ans[aa.a]*ans[aa.b];
q1.push(aa);
aa.a++;aa.b--;
aa.data=ans[aa.a]*ans[aa.b];
q1.push(aa);
}
printf("%lld\n",sum);
return ;
}

Bzoj 3131 [Sdoi2013]淘金 题解的更多相关文章

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

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

  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 3124: [Sdoi2013]直径 题解

    3124: [Sdoi2013]直径 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1222  Solved: 580[Submit][Status] ...

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

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

  7. 题解-SDOI2013 淘金

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

  8. BZOJ 1003 物流运输 题解 【SPFA+DP】

    BZOJ 1003 物流运输 题解 Description 物流公司要把一批货物从码头A运到码头B.由于货物量比较大,需要n天才能运完.货物运输过程中一般要转停好几个码头.物流公司通常会设计一条固定的 ...

  9. BZOJ 1191 超级英雄 Hero 题解

    BZOJ 1191 超级英雄 Hero 题解 Description 现在电视台有一种节目叫做超级英雄,大概的流程就是每位选手到台上回答主持人的几个问题,然后根据回答问题的多少获得不同数目的奖品或奖金 ...

随机推荐

  1. php延时执行

    sleep(秒) usleep(毫秒) 让它睡上一会.

  2. 【图文教程】de4dot实战字符串解密(演示:hishop微分销系统)

    原文:[图文教程]de4dot实战字符串解密(演示:hishop微分销系统) 前些日子,公司需求开发一个微分销系统,于是找来hishop微分销系统想借鉴一下,没想到里面各种加密,就连字符串也都加密了. ...

  3. 图像滤镜艺术---微软自拍APP滤镜实现合集DEMO

    原文:图像滤镜艺术---微软自拍APP滤镜实现合集DEMO 微软最近推出了自家的美颜app,大家有兴趣可以在苹果商店中下载一下看一看,今天,我们要说的便是这款app中的所有滤镜实现问题. 这款app中 ...

  4. Win8Metro(C#)数字图像处理--2.18图像平移变换

    原文:Win8Metro(C#)数字图像处理--2.18图像平移变换  [函数名称] 图像平移变换函数TranslationProcess(WriteableBitmap src,int x,in ...

  5. imp dll时遇见的非常恶心的问题

    我需要导入dll库中这样一个函数VM661JTCPDLL_API int admin_login(sel_admin_ret* sel_admins, int num, char* admin_nam ...

  6. eclipse 插件编写(一)

    由于项目开发进程中有一些重复性的代码进行编写,没有任何业务逻辑,粘贴复制又很麻烦且容易出错,故想起做一个eclipse插件来满足一下自己的工作需要,同时记录一下,以供以后参考与共同学习.本文主要讲解一 ...

  7. storm(二)消息的可靠处理

    storm 通过 trident保证了对消息提供不同的级别.beast effort,at least once, exactly once. 一个tuple 从spout流出,可能会导致大量的tup ...

  8. python 动态调用模块&类&方法

    转载自:http://www.cnblogs.com/bluefrog/archive/2012/05/11/2496439.html 一直想知道python里有没有类似php中的 $classnam ...

  9. UWP ObservableCollection<Evaluate>集合中ObservableCollection<PictureInfo>变更通知到xaml界面

    ObservableCollection<Evaluate> EvaluateList = new ObservableCollection<Evaluate>();//评论集 ...

  10. nginx(一) nginx详解

    nginx是一个被广泛使用的集群架构组件,我们有必要对它有足够的了解.下面将先认识nginx:包括应用场景.nginx基本架构.功能特性.并发模型以及配置说明,最后我们再总结下,为什么选择nginx的 ...