bzoj3131
这是一道很好也很烦的综合题……
首先我们肯定要先把f(i)处理出来这是毫无疑问的
我们要求出数位乘积为now的个数,首先是空间上的问题
直接肯定会爆空间,不难发现
乘积的质因数只有2,3,5,7,并且指数也不是特别大
暴力可得到不同的乘积最多只有15000不到
然后我们就可以对其离散化然后数位dp
dp完之后,对于点(p,q),这上面的金子个数是sum(p)*sum(q)个 (sum表示数位乘积为p的数的个数)
然后我们要求金子前k多的点,当状态太多无法算出所有状态求最优值时,我们常常用堆来维护
首先我们对sum排序(假定降序),对于每个乘积x,设乘积x离散化后对应的编号为w(x)
在x行上金子最多的点一定是sum[w(x)]*sum[1],次大的点一定是sum[w(x)]*sum[2]……
然后我们对当前这n行上最多的点维护一个大根堆
当我们每次将堆顶的点取出时,堆顶所在行的下一大的点可能是之后选取结果产生影响,
因此我们要将这行下一大的点加入堆,一共只要弹k次,所以复杂度为O(klogt)
const maxn=;
mo=; type arr=array[..maxn] of int64; var a,sum,h,loc,num:arr;
b:array[..] of int64;
f:array[..,..maxn] of int64;
n,ans,x:int64;
c,m,t,i:longint; procedure swap(var a,b:int64);
var c:int64;
begin
c:=a;
a:=b;
b:=c;
end; procedure sort(l,r:longint;var a:arr);
var i,j:longint;x,y:int64;
begin
i:=l;
j:=r;
x:=a[(l+r) shr ];
repeat
while a[i]<x do inc(i);
while x<a[j] do dec(j);
if i<=j then
begin
swap(a[i],a[j]);
inc(i);
dec(j);
end;
until i>j;
if i<r then sort(i,r,a);
if j>l then sort(l,j,a);
end; procedure prepare;
var i,j,k,l:int64;
begin
i:=;
while i<=n do
begin
j:=i;
while j<=n do
begin
k:=j;
while k<=n do
begin
l:=k;
while l<=n do
begin
inc(m);
a[m]:=l;
l:=l*;
end;
k:=k*;
end;
j:=j*;
end;
i:=i*;
end;
sort(,m,a);
end; procedure work;
begin
t:=;
x:=n;
while x<> do
begin
inc(t);
b[t]:=x mod ;
x:=x div ;
end;
end; function find(l,r:longint;x:int64):longint;
var mid:longint;
begin
while l<r do
begin
mid:=(l+r)shr ;
if a[mid]=x then exit(mid);
if a[mid]<x then l:=mid+ else r:=mid-;
end;
if a[l]=x then exit(l);
exit();
end; procedure count;
var i,j,k:longint;
now,y:int64;
begin
work;
f[][]:=; //f[i,j]表示到第i位,乘积为j(j是离散化后的排名)的方案数
for i:= to t- do
for j:= to m do
for k:= to do
if (a[j] mod k=) then
f[i,j]:=f[i,j]+f[i-,find(,j,a[j] div k)]; now:=;
for i:=t downto do
begin
for j:= to b[i]- do //肯定不可能是0
for k:= to m do
if (a[k]>=now*j) and ((a[k] div now) mod j=) and (a[k] mod now=) then
sum[k]:=sum[k]+f[i-,find(,k,a[k] div (now*j))];
now:=now*b[i];
if now= then break;
end;
if now<> then inc(sum[find(,m,now)]);
for i:= to m do
for j:= to t- do
sum[i]:=sum[i]+f[j,i];
end; procedure sift(i,n:longint);
var j:longint;
x:int64;
begin
x:=h[i];
j:=i shl ;
while j<=n do
begin
if (j<n) and (h[j]<h[j+]) then inc(j);
if x>=h[j] then exit
else begin
swap(h[i],h[j]);
swap(loc[i],loc[j]);
swap(num[i],num[j]);
i:=j;
j:=j shl ;
end;
end;
end; begin
readln(n,c);
prepare;
work;
count;
sort(,m,sum); //为了统一形式,这里是升序
for i:= to m do
begin
h[i]:=sum[i]*sum[m]; //当前第i行上最大的点
loc[i]:=m;
num[i]:=i; //所代表的行
end;
for i:=m downto do
sift(i,m);
ans:=;
for i:= to c do
begin
ans:=(ans+(h[] mod mo)) mod mo;
dec(loc[]); //加入这行下一大的点
h[]:=sum[num[]]*sum[loc[]];
sift(,m);
end;
writeln(ans);
end.
bzoj3131的更多相关文章
- [BZOJ3131] [Sdoi2013]淘金
[BZOJ3131] [Sdoi2013]淘金 Description 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1..N.初始的时候,所有的整数坐 ...
- bzoj千题计划268:bzoj3131: [Sdoi2013]淘金
http://www.lydsy.com/JudgeOnline/problem.php?id=3131 如果已知 s[i]=j 表示有j个<=n数的数码乘积=i 那么就会有 s[a1]*s[a ...
- [您有新的未分配科技点]数位DP:从板子到基础(例题 bzoj1026 windy数 bzoj3131 淘金)
只会统计数位个数或者某种”符合简单规律”的数并不够……我们需要更多的套路和应用 数位dp中常用的思想是“分类讨论”思想.下面我们就看一道典型的分类讨论例题 1026: [SCOI2009]windy数 ...
- 【数位dp】bzoj3131: [Sdoi2013]淘金
思路比较自然,但我要是考场上写估计会写挂:好像被什么不得了的细节苟住了?…… Description 小Z在玩一个叫做<淘金者>的游戏.游戏的世界是一个二维坐标.X轴.Y轴坐标范围均为1. ...
- [Bzoj3131][Sdoi2013]淘金(数位dp)(优先队列)
3131: [Sdoi2013]淘金 Time Limit: 30 Sec Memory Limit: 256 MBSubmit: 847 Solved: 423[Submit][Status][ ...
- [bzoj3131]淘金[sdoi2013][数位DP]
求出每个数i可以被转移到的数目$f[i]$,则点$(i,j)$中的金子数目为$f[i]*f[j]$,我们就可以用优先队列求解前$k$大. 首先所有的积数目在$10^4$左右,可以先Dfs搜索出所有的数 ...
- bzoj2757
非常神的数位dp,我调了几乎一天首先和bzoj3131类似,乘积是可以预处理出来的,注意这里乘积有一个表示的技巧因为这里质因数只有2,3,5,7,所以我们可以表示成2^a*3^b*5^c*7^d,也就 ...
- 【Richard 的刷(水)题记录】
大概想了想,还是有个记录比较好. 9/24 网络流一日游: 最大流:bzoj1711[Usaco2007 Open]Dining 拆点 BZOJ 3993 Sdoi2015 星际战争 二分 P.S.这 ...
- OI动态规划&&优化 简单学习笔记
持续更新!! DP的难点主要分为两类,一类以状态设计为难点,一类以转移的优化为难点. DP的类型 序列DP [例题]BZOJ2298 problem a 数位DP 常用来统计或者查找一个区间满足条件的 ...
随机推荐
- js如何打印object对象
js调试中经常会碰到输出的内容是对象而无法打印的时候,光靠alert只能打印出object标示,却不能打印出来里面的内容,甚是不方便,于是各方面整理总结了如下一个函数,能够将数组或者对象这类的结果一一 ...
- SQL Cursor 游标的使用
DECLARE @name VARCHAR(50) --声明游标 DECLARE cursor_VAA1 CURSOR FOR SELECT VAA05 FROM VAA1 --打开游标 OPEN ...
- 【转】浅析Windows编程的剪贴板
摘要: 本文对Windows剪贴板机制作了深入.全面的阐述,具体内容包括:文本.位图.DSP.自定义格式剪贴板的使用和多数据项和延迟提交技术. 关键词: VC++6.0: 剪贴板机制:数据格式:延迟提 ...
- php session_id()函数介绍及代码实例
session_id()功能: 获取设置当前回话ID. 函数说明: string session_id ([ string $id ] ) 参数: 如果指定了参数$id,那么函数会替换当前的回话id. ...
- /etc/sysconfig/目录详解
/etc/sysconfig/目录包括了在红帽企业LINUX下各种系统配置文件,以下是在/etc/sysconfig/目录下的文件列表如图: 500)this.width=500;"> ...
- vmstat,iostat,sar命令详解
Procs r: 等待运行的进程数 b: 处在非中断睡眠状态的进程数 w: 被交换出去的可运行的进程数.此数由 linux 计算得出,但 linux 并不耗尽交换空间 Memory swpd: 虚拟内 ...
- oracle linux下oracle 10g启动EM、isqlplus及相关命令语法
转载:http://hancang2000.blog.sohu.com/139239421.html ORACLE_HOME/bin/emctl start dbconsole $ORACLE_HOM ...
- 关于tableView的那些坑(一)—— automaticallyAdjustsScrollViewInsets属性
最近用tabbar来切换控制器,用childViewController来实现多控制器管理,多列表切换,在子控制器中设置了automaticallyAdjustsScrollViewInsets属性为 ...
- java web 文件上传下载
文件上传下载案例: 首先是此案例工程的目录结构:
- Mac OS 安装 Port
简介 MacPorts类似与apt-get以及yum等软件包管理工具,可以方便的进行安装与卸载软件的功能,同时可以自动安装软件包的依赖,非常方便,同类的还有brew等工具. 安装 下载MacPorts ...