zoukankan      html  css  js  c++  java
  • Heaven Cow与God Bull【数论】【高精】

    题目大意:

    给定一个整数n,求一个整数m,满足mn,并且mφ(m)的值最大。


    思路:

    明显是一道数论题目。遇到数论先达表,打个表试试看。
    满足mφ(m)=max(iφ(i))(i=1..m)m有:2,6,30,210,2310,30300...
    将这些数字分解质因数
    2=2
    6=2×3
    30=2×3×5
    210=2×3×5×7
    2310=2×3×5×7×11
    30300=2×3×5×7×11×13
    ...
    规律也就自然出来了。
    m满足m=Πi=1kprime[i]时符合要求。
    回到题目,这道题n1×1025000,所以肯定要用压位高精。
    先预处理处不大于60000的所有质数,同时求出符合要求的num[i],最终枚举num[i],输出不大于n的最大num[i]
    由于压5位内存会爆炸,压多位会炸int,所以我采用的是压10位long long


    代码:

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <string>
    #define maxn 2510
    using namespace std;
    
    long long p[10001],t,n[maxn+1],num[10001][maxn+1],m,sum,len,j,k;
    string s;
    
    bool check(long long x)
    {
        if (x==1) return false;
        if (x==2||x==3) return true;
        if(x%6!=1&&x%6!=5) return false;
        for(long long i=5;i*i<=x;i+=6)
         if((!(x%i))||(!(x%(i+2)))) return false;
        return true;
    }
    
    bool check_ans(long long x)
    {
        for (long long i=1;i<=maxn;i++)
         if (n[i]>num[x][i]) return false;
         else if (n[i]<num[x][i]) return true;
        return false;
    }
    
    int main()
    {
        num[0][maxn]=1;
        for (long long i=1;i<=60000;i++)  //求质数
         if (check(i))   //找到质数
         {
            p[++sum]=i;
            t=0;
            for (long long j=maxn;j>=1;j--)  //求对应的num[i]
            {
                num[sum][j]=num[sum-1][j]*p[sum]+t;
                t=num[sum][j]/10000000000;
                num[sum][j]%=10000000000;
            }
         }
        scanf("%lld",&m);
        while (m--)
        {
            memset(n,0,sizeof(n));
            cin>>s;
            len=s.size();
            for (long long i=0;i<len;i++)
             n[maxn-(len-1)/10+(10-((len-1)%10+1)+i)/10]=n[maxn-(len-1)/10+(10-((len-1)%10+1)+i)/10]*10+s[i]-48;  //压位数字读入,一定要推准
            for (k=1;k<=sum;k++)  //枚举num[i]
             if (check_ans(k)) break;
            k--;
            j=1;
            while (!num[k][j]) j++;
            printf("%lld",num[k][j++]);
            for (;j<=maxn;j++)  //输出
            {
                if (num[k][j]<10) printf("000000000");
                else if (num[k][j]<100) printf("00000000");
                else if (num[k][j]<1000) printf("0000000");
                else if (num[k][j]<10000) printf("000000");
                else if (num[k][j]<100000) printf("00000");
                else if (num[k][j]<1000000) printf("0000");
                else if (num[k][j]<10000000) printf("000");
                else if (num[k][j]<100000000) printf("00");
                else if (num[k][j]<1000000000) printf("0");
                printf("%lld",num[k][j]);
            }
            printf("\n");
        }
        return 0;
    }
  • 相关阅读:
    SAP S/4HANA extensibility扩展原理介绍
    SAP CRM系统订单模型的设计与实现
    使用nodejs代码在SAP C4C里创建Individual customer
    SAP Cloud for Customer Account和individual customer的区别
    Let the Balloon Rise map一个数组
    How Many Tables 简单并查集
    Heap Operations 优先队列
    Arpa’s obvious problem and Mehrdad’s terrible solution 思维
    Passing the Message 单调栈两次
    The Suspects 并查集
  • 原文地址:https://www.cnblogs.com/hello-tomorrow/p/11998829.html
Copyright © 2011-2022 走看看