数学——洛谷P1128 [HNOI2001]求正整数

来源:互联网 发布:淘宝申诉小票 编辑:程序博客网 时间:2024/05/30 04:48

https://www.luogu.org/problem/show?pid=1128
我们sxyz的模拟赛质量真的是;
我靠这道题直接就放到noip模拟赛里面来了;
好气啊;
首先假如答案是ans
ans分解质因数
2^a1+3^a2+5^a3……
那么他的因子个数就是
(a1+1) * (a2+1)(a3+1)……
为什么?乘法原理;
所以我们读入一个n
直接把n分解质因数;
a1 a2 a3….
然后每个a减去1;
这些a就是构成ans的质数的指数;
比如n=4
4=2*2
2-1=1
所以两个指数1 1
2^1*3^1=6;
为什么?我靠大佬都说找规律;
然后就是搜索每个指数用那个指质数做底数;
然后用log去避免高精;
在最后用高精度去存答案;
我靠我也不知道;

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>#include<cmath>using namespace std;const int NN=1e7;const int N=7;struct H{int a[3000],len;}a;void outit(H a){    printf("%d",a.a[a.len]);    for(int i=a.len-1;i;i--){        for(int k=NN/10;a.a[i]<k;k/=10)printf("0");        if(a.a[i])printf("%d",a.a[i]);     }printf("\n");  }H chen(H a,H b){    H z;    z.len=a.len+b.len+2;    for(int i=1;i<=a.len;i++)    for(int j=1;j<=b.len;j++)z.a[i+j-1]+=(a.a[i]*b.a[j]);    for(int i=1;i<=z.len;i++)z.a[i+1]+=z.a[i]/NN,z.a[i]%=NN;        while(z.len>1&&!z.a[z.len])z.len--;    return z;}void cheng(int x){    for(int i=1;i<=a.len;i++)a.a[i]*=x;    for(int i=1;i<=a.len;i++){        a.a[i+1]+=a.a[i]/NN;        a.a[i]%=NN;    }    while(a.a[a.len+1]){        a.len++;a.a[a.len+1]+=a.a[a.len]/NN;a.a[a.len]%=NN;    }}int pri[18]={12,2,3,5,7,11,13,17,19,23,29,31,37};int q[50005],top,c[18],an[18];double hh[18],ans=1e6;int n;void make(){    for(int i=1;i<=pri[0];i++)hh[i]=log2(pri[i]);    for(int i=n;i;i--)if(n%i==0)q[++top]=i;}void get(double x){    ans=x;    for(int i=1;i<=12;i++)an[i]=c[i];}void dfs(int x,int now,int t,double temp){    if(ans<=temp)return;    if(now==1){get(temp);return;}    if(x>pri[0])return;    for(int i=t;i<=top;i++)        if(now%q[i]==0){            c[x]=q[i]-1;            dfs(x+1,now/q[i],i,temp+hh[x]*(q[i]-1));            c[x]=0;        }}int main(){    scanf("%d",&n);    make();    dfs(1,n,1,0);    a.a[1]=1;    a.len=1;    for(int i=1;i<=12;i++)        for(int j=1;j<=an[i];j++)cheng(pri[i]);    outit(a);}
原创粉丝点击