题意:对于任意输入的正整数n,请编程求出具有n个不同因子的最小正整数m。

n<=50000

思路:记得以前好像看的是maigo的题解

n即为将m分解为质数幂次的乘积后的次数+1之积

经检验只需要取前16个质数

其次幂次的数据单调不增

乘积大小比较时候表示为ln之和,这样比较巧妙的避开了大整数比较

加了这几个优化跑的飞快

注意需要加高精

C++

 #include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<map>
#include<set>
#include<cmath>
int prime[]={,,,,,,,,,,,,,,,,};
int a[],b[],c[],d[],ans[],s[];
double f[];
int n,ansp;
double anse; void dfs(int n,int p,int limit,double e)
{
if(n==)
{
if(e<anse)
{
for(int i=;i<=;i++) ans[i]=s[i];
anse=e;
ansp=p;
}
exit;
}
for(int i=;i<=limit;i++)
if(!(n%(i+)))
{
s[p]=i;
dfs(n/(i+),p+,i,e+f[p]*i);
}
} void mult1(int *a,int *b,int *c)
{
for(int i=;i<=c[];i++) c[i]=;
c[]=;
for(int i=;i<=a[];i++)
for(int j=;j<=b[];j++)
{
int k=i+j-;
c[k]+=a[i]*b[j];
c[k+]+=c[k]/;
c[k]%=;
}
c[]=a[]+b[];
if(!c[c[]]) c[]--;
} void mult2(int *a,int b)
{ for(int i=;i<=a[];i++) a[i]*=b;
for(int i=;i<=a[]-;i++)
{
a[i+]+=a[i]/;
a[i]%=;
}
while(a[a[]]>)
{
a[a[]+]=a[a[]]/;
a[a[]]%=;
a[]++;
}
} void pow(int *x,int *y,int k,int p)
{
if(k==)
{
for(int i=;i<=x[];i++) x[i]=;
x[]=;
if(prime[p]<)
{
x[]=; x[]=prime[p];
}
else
{
x[]=; x[]=prime[p]/; x[]=prime[p]%;
}
}
else
{
pow(y,x,k>>,p);
mult1(y,y,x);
if(k&) mult2(x,prime[p]);
} } void print(int *a)
{
for(int i=a[];i>;i--) printf("%d",a[i]);
printf("\n");
} int main()
{
freopen("bzoj1225.in","r",stdin);
freopen("bzoj1225.out","w",stdout);
scanf("%d",&n);
for(int i=;i<=;i++) f[i]=log(prime[i]);
anse=3e38;
dfs(n,,n-,);
ansp--;
a[]=; a[]=;
for(int i=;i<=ansp;i++)
{
pow(c,d,ans[i],i);
if(i&) mult1(a,c,b);
else mult1(b,c,a);
}
if(ansp&) print(b);
else print(a);
}

pascal

 type arr=array[-..]of longint;
const base=;
prime:array[..]of longint=(,,,,,,,,,
,,,,,,); var s,ans:array[..]of longint;
n,ansp:longint;
anse:real;
a,b,c,d:arr;
bool:boolean; procedure dfs(n,p,limit:longint;e:real);
var i:longint;
begin
if n= then
begin
if e<anse then begin ans:=s; anse:=e; ansp:=p; end;
exit;
end;
for i:= to limit do
if n mod (i+)= then
begin
s[p]:=i;
dfs(n div (i+),p+,i,e+ln(prime[p])*i);
end;
end; procedure lyk(var a:arr;b:longint);
var i:longint;
begin
for i:= to a[-] do a[i]:=a[i]*b;
for i:= to a[-] do
begin
inc(a[i+],a[i] div base);
a[i]:=a[i] mod base;
end;
if a[a[-]+]> then inc(a[-]);
end; procedure zhw(var a,b,c:arr);
var i,j,k:longint;
begin
fillchar(c,sizeof(c),);
for i:= to a[-] do
for j:= to b[-] do
begin
k:=i+j;
inc(c[k],a[i]*b[j]);
inc(c[k+],c[k] div base);
c[k]:=c[k] mod base;
end;
c[-]:=a[-]+b[-];
if c[c[-]+]> then inc(c[-]);
end; procedure pow(var x,y:arr;p:longint);
begin
if p= then
begin
fillchar(x,sizeof(x),);
x[]:=prime[n];
end
else
begin
pow(y,x,p>>);
zhw(y,y,x);
if p and = then lyk(x,prime[n]);
end;
end;
procedure print(var a:arr);
var i:longint;
begin
write(a[a[-]]);
for i:=a[-]- downto do
write(a[i] div ,a[i] div mod ,a[i] div mod ,a[i] mod );
writeln;
end; begin readln(n);
anse:=3e38;
dfs(n,,n-,);
dec(ansp);
fillchar(a,sizeof(a),);
a[]:=;
for n:= to ansp do
begin
pow(c,d,ans[n]);
if n and = then zhw(a,c,b)
else zhw(b,c,a);
end; if ansp and = then print(b)
else print(a); end.

【BZOJ1225】求正整数(数论)的更多相关文章

  1. 高精度+搜索+质数 BZOJ1225 [HNOI2001] 求正整数

    // 高精度+搜索+质数 BZOJ1225 [HNOI2001] 求正整数 // 思路: // http://blog.csdn.net/huzecong/article/details/847868 ...

  2. bzoj1225 [HNOI2001] 求正整数

    1225: [HNOI2001] 求正整数 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 762  Solved: 313[Submit][Statu ...

  3. 求正整数n所有可能的和式的组合(如;4=1+1+1+1、1+1+2、1+3、2+1+1、2+2

    作者:张小二 nyoj90 ,可以使用递归的方式直接计算个数,也可以通过把满足的个数求出来计数,因为在juLy博客上看到整数划分,所以重写了这个代码,就是列出所m的可能性,提交后正确.acmer的入门 ...

  4. BZOJ 1225: [HNOI2001] 求正整数( dfs + 高精度 )

    15 < log250000 < 16, 所以不会选超过16个质数, 然后暴力去跑dfs, 高精度计算最后答案.. ------------------------------------ ...

  5. 实验一:实现求正整数1-N之间所有质数的功能,并进行测试。

    实验一 Java开发环境的熟悉(Linux + Eclipse) 实验内容 1.使用JDK编译.运行简单的Java程序: 2.使用Eclipse 编辑.编译.运行.调试Java程序. 命令行下的程序开 ...

  6. luogu P1128 [HNOI2001]求正整数 dp 高精度

    LINK:求正整数 比较难的高精度. 容易想到贪心不过这个贪心的策略大多都能找到反例. 考虑dp. f[i][j]表示前i个质数此时n的值为j的最小的答案. 利用高精度dp不太现实.就算上FFT也会T ...

  7. 求正整数2和n之间的完全数

    [题目描述] 求正整数22和nn之间的完全数(一行一个数). 完全数:因子之和等于它本身的自然数,如6=1+2+36=1+2+3 [输入] 输入n(n≤5000)n(n≤5000). [输出] 一行一 ...

  8. [HNOI2001] 求正整数 - 背包dp,数论

    对于任意输入的正整数n,请编程求出具有n个不同因子的最小正整数m. Solution (乍一看很简单却搞了好久?我真是太菜了) 根据因子个数计算公式 若 \(m = \prod p_i^{q_i}\) ...

  9. 【BZOJ】1225: [HNOI2001] 求正整数

    http://www.lydsy.com/JudgeOnline/problem.php?id=1225 题意:给一个数n,求一个最小的有n个约数的正整数.(n<=50000) #include ...

随机推荐

  1. [转]Android专家级别的面试总结

    Android专家级别的面试总结 2017年02月15日 16:56:28 阅读数:1225 1.. 自定义View流程 onMeasure, onLayout, onDraw, 采用深度优先,因为必 ...

  2. angular(一)路由的配置(1)

    本篇文章是最近在公司里做项目的时候,尝试配置路由的过程.由于头尾,和路由主体,包括控制器组长都已配置好,我这里只是单纯的写一些配置单个副页面的过程.大家肯定会有看不懂的地方,后续会陆续更新完整的配置全 ...

  3. 微信小程序 可用性一览

    1. 调试vConsole微信小程序通过vConsole的形式观察控制台打印.打印到vConsole控制台的是由 JSON 转化的字符串.这还是可以起到调试作用的. Source Map当es6 转  ...

  4. JavaScript创建对象的七种方法

    一. 工厂模式 创建: function createPerson(name,behavior){ var p=new Object(); p.name=name; p.behavior=behavi ...

  5. Android利用Socket与硬件通信之智能家居APP

    前几天做一个智能家居APP,硬件段使用的是ESP8266WIFI模块,其实不管是WIFI模块还是蓝牙,通信都是同样一个道理,获取IP和端口来进行通信. 我是通过XCOM v2.0 发送信息,移动端接收 ...

  6. (转)新手学习System Verilog & UVM指南

    从刚接触System Verilog以及后来的VMM,OVM,UVM已经有很多年了,随着电子工业的逐步发展,国内对验证人才的需求也会急剧增加,这从各大招聘网站贴出的职位上也可以看出来,不少朋友可能想尽 ...

  7. webapi之fiddler头设置

    Host: localhost:16648Connection: keep-aliveContent-Length: 36Accept: application/json, text/javascri ...

  8. FPGA-信号边缘检测

    在FPGA逻辑电路中,输入信号的边缘检测是一个常用的操作,这算是FPGA的基本功之一. 信号边缘检测应用十分广泛,例如:通信协议的时序操作,按键的检测等,都应用到按键的检测.按键的检测分为上升沿和下降 ...

  9. 北京区域赛I题,Uva7676,A Boring Problem,前缀和差分

    转载自https://blog.csdn.net/weixin_37517391/article/details/83821752 题解 其实这题不难,只要想到了前缀和差分就基本OK了. 我们要求的是 ...

  10. expand - 把 tab 符转换为空格符

    总览 (SYNOPSIS) ../src/expand [OPTION]... [FILE]... 描述 (DESCRIPTION) 把 各文件 FILE 中的 tab 符 转换为 空格符, 然后 写 ...