zoukankan      html  css  js  c++  java
  • 1171: lfx捧杯稳啦!

    Lfx在复习离散的时候突然想到了一个算法题,毕竟是lfx,

    算法题如下:

    他想知道这样的问题,先定义1~n中即是3的倍数,又是11的倍数的那些数的和sum,

    他想知道sum有多少个质因子,以及1~sum-1中有多少个数与sum互质?

    1<= N <= 1e6

    输入:

    一个整数n

    输出

    两个整数,分别代表sum质因子的数量以及1~sum-1中与sum互质的数量。

    思路:

    先1~n扫一下求sum值,然后用唯一分解定理求质因子的数量,用欧拉函数求互质的数量。

    唯一分解定理的步骤:

    先打一个素数表,方法有很多种,然后用已知的素数去分解数值。

    对于一个数x,小于x并与x互质的数的数量就是欧拉函数的定义,一个数论函数,很基础。

    不知道的新名词应该去学习一下。

    细节见代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #include <iomanip>
    #define ALL(x) (x).begin(), (x).end()
    #define rt return
    #define dll(x) scanf("%I64d",&x)
    #define xll(x) printf("%I64d
    ",x)
    #define sz(a) int(a.size())
    #define all(a) a.begin(), a.end()
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define eps 1e-6
    #define gg(x) getInt(&x)
    #define db(x) cout<<"== [ "<<x<<" ] =="<<endl;
    using namespace std;
    typedef long long ll;
    ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
    ll powmod(ll a,ll b,ll MOD){ll ans=1;while(b){if(b%2)ans=ans*a%MOD;a=a*a%MOD;b/=2;}return ans;}
    inline void getInt(int* p);
    const int inf=0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    const int maxn = 1e6+50;
    bool noprime[maxn+50];
    vector <int> p;
    int getPrime()
    {
        // 华丽的初始化
        memset(noprime,false,sizeof(noprime));
        p.clear();
     
        int m=(int)sqrt(maxn+0.5);
        // 多姿的线性筛
        for(int i=2;i<=m;i++)
        {
            if(!noprime[i])
            {
                for(int j=i*i;j<=maxn;j+=i)
                {
                    noprime[j] = true;
                }
            }
        }
        // 把素数加到vector里
        for(int i=2;i<=maxn;i++)
        {
            if(!noprime[i])
            {
                p.push_back(i);
            }
        }
        //返回vector的大小
        return p.size();
     
    }
    int pf[105][2];// 0 -> value 1->count
     
    int getPrifac( ll n,int len)
    {
        int pos = 0;
        for(int i=0; p[i]*p[i]<=n&&i<len;i++)
        {
            if( n% p[i] == 0)
            {
                pf[++pos][0]=p[i];
                pf[pos][1]=0;
                // 算质因数的幂数
                while(n%p[i]==0)
                {
                    pf[pos][1]++;
                    n/=p[i];
                }
            }
        }
        if( n> 1)
        {
            pf[++pos][0] = n;
            pf[pos][1]=1;
        }
        return pos; // 优美的返回有多少个质因数
        // 1~pos
    }
    ll euler(ll n) { //log(n)时间内求一个数的欧拉值
        ll ans = n;
        for (ll i = 2; i*i <= n; i++) {
            if (n%i == 0)
            {
                ans -= ans / i;
                while (n%i == 0) n /= i;
            }
        }
        if (n>1) ans -= ans / n;
        return ans;
    }
    int main()
    {
        int len=getPrime();
        int n;
        gg(n);
        ll cnt=0ll;
        repd(i,1,n)
        {
            if((i%3==0)&&(i%11==0))
            {
                cnt+=i;
            }
        }
        // db(cnt);
        int num=getPrifac(cnt,len);
        printf("%d ",num);
        printf("%lld
    ",euler(cnt) );
     
        return 0;
    }
     
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }

    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    搭建视频网站光线cms
    Linux FTP服务配置
    Chromium下载地址
    Ubuntu Server批量ping选择最快源
    vs2010扩展
    私有云
    mssql格式化输出
    CSLA .NET 3.6支持Silverlight 2
    Unity Application Block 1.2 for Silverlight December 2008
    silverlight寻奇 Graphite
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/10393296.html
Copyright © 2011-2022 走看看