zoukankan      html  css  js  c++  java
  • 【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("
    ");
     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.
  • 相关阅读:
    DES加密和解密PHP,Java,ObjectC统一的方法
    TreeSaver 使用教程整理——Step 3: Creating Grids
    android面试题目汇总持续更新
    Android SQLiteHelper
    Android计算地图上两点距离
    asp.net 下载文件几种方式
    android 权限
    ORA01795的原因及解决办法
    C# winFrom 通过注册新协议实现网页链接打开本地程序
    Android 读SIM卡信息
  • 原文地址:https://www.cnblogs.com/myx12345/p/9319681.html
Copyright © 2011-2022 走看看