zoukankan      html  css  js  c++  java
  • A

    /**
    题目:A - Bi-shoe and Phi-shoe
    链接:https://vjudge.net/contest/154246#problem/A
    题意:每一个数都有一个得分,它的得分就是,假定这个数为n,那么<n且与n互质的数的个数就是n的得分;
    注意这里<n说明不是完全求欧拉函数,当n=1的时候值为0;其他和欧拉函数求法一样。
    现在给定n个数xi,对每一个数xi找一个最小的满足条件的数yi,使得yi的得分>=xi这个数。
    求n个数xi对应找出来的yi的和。
    思路:
    第一种做法
    递推求出欧拉函数数组,然后特殊处理1的值设定为0;
    然后对要求的n个数排序,从小到大找一个满足条件的yi,之后的数肯定在大于等于yi的数中找。
    不断将yi后移就行了。仔细想想就明白了。
    第二种做法
    不需要排序,预处理递推数组后,因为素数r的欧拉函数之为r-1;而两个素数之间的距离不超过log(r);
    那么对每一个数xi可以从自身开始向上递增最多log(xi)就可以找到>=xi的欧拉函数;
    */
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    const int maxn = 1000100;
    ///获得单个数的欧拉函数
    /*
    ll getEuler(ll x)
    {
        ll res = x;
        for(int i = 2; i*i<=x; i++){
            if(x%i==0){
                res = res/i*(i-1);
                while(x%i==0) x/=i;
            }
        }
        if(x>1){
            res = res/x*(x-1);
        }
        return res;
    }*/
    int a[10005];
    int n, cas=1;
    ll euler[maxn];
    ///递推求一段欧拉函数,非最简版
    void Eulers(ll x)
    {
        int mas = 0;
        for(int i = 1; i <= x; i++) euler[i] = i;
        for(int i = 2; i <= x; i++) {
            if(euler[i]==i){//判断素数
                for(int j = i; j <= x; j+=i){
                    euler[j]=euler[j]/i*(i-1);
                }
            }
        }
        ///由于本题目要求<n的欧拉函数,不可以等于n;所以当n为1的时候,满足条件的个数为0;
        ///****************************实际上1的欧拉函数值为1;所以这里是一个针对本题的特例才要改为0;
        euler[1] = 0;
    }
    void solve1()
    {
        sort(a,a+n);
        int p = 1;
        ll ans = 0;
        for(int i = 0; i<n; i++){
            while(euler[p]<a[i]){
                p++;
            }
            ans += p;
        }
        printf("Case %d: %lld Xukha
    ",cas++,ans);
    }
    void solve2()
    {
        ll ans = 0;
        for(int i = 0; i<n; i++){
            for(int j = a[i]; 1; j++){///两个素数之间距离最多log(n);
                if(euler[j]>=a[i]){
                    ans += j; break;
                }
            }
        }
        printf("Case %d: %lld Xukha
    ",cas++,ans);
    }
    int main()
    {
        int T;
        Eulers(maxn);
        cin>>T;
        while(T--){
            scanf("%d",&n);
            for(int i = 0; i<n; i++) scanf("%d",&a[i]);
            //solve1();
            solve2();
            //printf("euler(%lld) = %lld
    ",x,getEuler(x));
            //printf("MAX(euler(%lld)) = %lld
    ",x,Eulers(x));
        }
        return 0;
    }
  • 相关阅读:
    字符集WideCharToMultiByte
    [HDF]hdf-4.2.6类库的使用
    [GDAL]读取HDF格式的calipso数据
    C#读写BitMap及颜色相乘
    [Slimdx]顶点和索引缓冲,绘制了2个分离的三角形
    [GDAL]写入shp
    几个环境学概念
    MIConvexHull
    几个力学概念
    [转载]如何破解Excel VBA密码
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/6558861.html
Copyright © 2011-2022 走看看