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;
}
原文地址:https://www.cnblogs.com/xiaochaoqun/p/6558861.html