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

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
#include
#include
#include
#include
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]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);
}

你可能感兴趣的:(数学——洛谷P1128 [HNOI2001]求正整数)