【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.
null