【BZOJ1225】求正整数(数论)

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

n<=50000

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

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

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

其次幂次的数据单调不增

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

加了这几个优化跑的飞快

注意需要加高精

C++

  1 #include<cstdio>
  2 #include<cstdlib>
  3 #include<algorithm>
  4 #include<iostream>
  5 #include<cstring>
  6 #include<map>
  7 #include<set>
  8 #include<cmath>
  9 int prime[17]={0,2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53};
 10 int a[50000],b[50000],c[50000],d[50000],ans[200],s[200];
 11 double f[20];
 12 int n,ansp;
 13 double anse;
 14 
 15 void dfs(int n,int p,int limit,double e)
 16 {
 17     if(n==1) 
 18     {
 19         if(e<anse) 
 20         {
 21             for(int i=0;i<=200;i++) ans[i]=s[i];
 22             anse=e;
 23             ansp=p;
 24         }
 25         exit;
 26     }
 27     for(int i=1;i<=limit;i++)
 28      if(!(n%(i+1)))
 29      {
 30          s[p]=i;
 31          dfs(n/(i+1),p+1,i,e+f[p]*i);
 32      }
 33 }
 34 
 35 void mult1(int *a,int *b,int *c)
 36 {
 37     for(int i=1;i<=c[0];i++) c[i]=0;
 38     c[0]=0;
 39     for(int i=1;i<=a[0];i++)
 40      for(int j=1;j<=b[0];j++)
 41      {
 42          int k=i+j-1;
 43          c[k]+=a[i]*b[j];
 44          c[k+1]+=c[k]/10;
 45          c[k]%=10;
 46      }
 47      c[0]=a[0]+b[0];
 48      if(!c[c[0]]) c[0]--;
 49 }
 50 
 51 void mult2(int *a,int b)
 52 {
 53 
 54     for(int i=1;i<=a[0];i++) a[i]*=b;
 55     for(int i=1;i<=a[0]-1;i++)
 56     {
 57         a[i+1]+=a[i]/10;
 58         a[i]%=10;
 59     }
 60     while(a[a[0]]>9)
 61     {
 62         a[a[0]+1]=a[a[0]]/10;
 63         a[a[0]]%=10;
 64         a[0]++;
 65     }
 66 }
 67 
 68 void pow(int *x,int *y,int k,int p)
 69 {
 70     if(k==1)
 71     {
 72       for(int i=1;i<=x[0];i++) x[i]=0;
 73       x[0]=0; 
 74       if(prime[p]<10)
 75       {
 76           x[0]=1; x[1]=prime[p];
 77       }
 78        else
 79        {
 80            x[0]=2; x[2]=prime[p]/10; x[1]=prime[p]%10;
 81        }
 82     }
 83      else 
 84      {
 85          pow(y,x,k>>1,p);
 86          mult1(y,y,x);
 87          if(k&1) mult2(x,prime[p]);
 88      }
 89    
 90 }
 91 
 92 void print(int *a)
 93 {
 94     for(int i=a[0];i>0;i--) printf("%d",a[i]);
 95     printf("\n");
 96 }
 97 
 98 int main()
 99 {
100     freopen("bzoj1225.in","r",stdin);
101     freopen("bzoj1225.out","w",stdout);
102     scanf("%d",&n);
103     for(int i=1;i<=17;i++) f[i]=log(prime[i]);
104     anse=3e38;
105     dfs(n,1,n-1,0);
106     ansp--;
107     a[0]=1; a[1]=1;
108     for(int i=1;i<=ansp;i++)
109     {
110         pow(c,d,ans[i],i);
111         if(i&1) mult1(a,c,b);
112          else mult1(b,c,a);
113     }
114     if(ansp&1) print(b);
115      else print(a); 
116 }

pascal

 1 type arr=array[-1..7000]of longint;
 2 const base=10000;
 3       prime:array[1..16]of longint=(2,3,5,7,11,13,17,19,23,
 4                                     29,31,37,41,43,47,53);
 5   
 6 var s,ans:array[0..200]of longint;
 7     n,ansp:longint;
 8     anse:real;
 9     a,b,c,d:arr;
10     bool:boolean;
11   
12 procedure dfs(n,p,limit:longint;e:real);
13 var i:longint;
14 begin
15  if n=1 then
16  begin
17   if e<anse then begin ans:=s; anse:=e; ansp:=p; end;
18   exit;
19  end;
20  for i:=1 to limit do
21   if n mod (i+1)=0 then
22   begin
23    s[p]:=i;
24    dfs(n div (i+1),p+1,i,e+ln(prime[p])*i);
25   end;
26 end;
27   
28 procedure lyk(var a:arr;b:longint);
29 var i:longint;
30 begin
31  for i:=0 to a[-1] do a[i]:=a[i]*b;
32  for i:=0 to a[-1] do
33  begin
34   inc(a[i+1],a[i] div base);
35   a[i]:=a[i] mod base;
36  end;
37  if a[a[-1]+1]>0 then inc(a[-1]);
38 end;
39   
40 procedure zhw(var a,b,c:arr);
41 var i,j,k:longint;
42 begin
43  fillchar(c,sizeof(c),0);
44  for i:=0 to a[-1] do
45   for j:=0 to b[-1] do
46   begin
47    k:=i+j;
48    inc(c[k],a[i]*b[j]);
49    inc(c[k+1],c[k] div base);
50    c[k]:=c[k] mod base;
51   end;
52   c[-1]:=a[-1]+b[-1];
53   if c[c[-1]+1]>0 then inc(c[-1]);
54 end;
55   
56 procedure pow(var x,y:arr;p:longint);
57 begin
58  if p=1 then
59  begin
60   fillchar(x,sizeof(x),0);
61   x[0]:=prime[n];
62  end
63   else
64   begin
65    pow(y,x,p>>1);
66    zhw(y,y,x);
67    if p and 1=1 then lyk(x,prime[n]);
68   end;
69 end;
70 procedure print(var a:arr);
71 var i:longint;
72 begin
73  write(a[a[-1]]);
74  for i:=a[-1]-1 downto 0 do
75   write(a[i] div 1000,a[i] div 100 mod 10,a[i] div 10 mod 10,a[i] mod 10);
76  writeln;
77 end;
78   
79 begin
80   
81  readln(n);
82  anse:=3e38;
83  dfs(n,1,n-1,0);
84  dec(ansp);
85  fillchar(a,sizeof(a),0);
86  a[0]:=1;
87  for n:=1 to ansp do
88  begin
89   pow(c,d,ans[n]);
90   if n and 1=1 then zhw(a,c,b)
91    else zhw(b,c,a);
92  end;
93   
94  if ansp and 1=1 then print(b)
95   else print(a);
96   
97 end.

猜你喜欢

转载自www.cnblogs.com/myx12345/p/9319681.html