Bi-shoe and Phi-shoe LightOJ

欧拉函数。

欧拉函数打表模板:

#define maxn 3000010
int p[maxn];
void oula(){
    int i,j;
    for(i=1; i<=maxn; i++)
        p[i]=i;
    for(i=2; i<=maxn; i+=2)
        p[i]/=2;
    for(i=3; i<=maxn; i+=2)
    if(p[i]==i)
    {
        for(j=i; j<=maxn; j+=i)
            p[j]=(p[j]/i*(i-1));
    }
}

题解:(说明:要不是看题解,自己真不敢这样写....,只能说数据有点弱。)

将欧拉函数打完表后,先将每个幸运数字排序一下。

然后枚举长度的同时,枚举每个幸运数字,如果当前长度对应的欧拉值大于等于幸运数字。直接就加上。

code1:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll INF=1e9+7;
const ll  maxn=1e6+10;
const ll N=1E6+20;
ll p[N];
ll arr[N];
ll dp[N];
void oula(){
    for(ll i=1;i<=maxn;i++) p[i]=i;
    for(ll i=2; i<=maxn; i+=2) p[i]/=2;
    for(ll i=3; i<=maxn; i+=2)
        if(p[i]==i){
            for(ll j=i; j<=maxn; j+=i)
                p[j]=(p[j]/i*(i-1));
        }
}
void solve(ll time){
    ll n;
    cin>>n;
    ll ans=0;
    for(ll i=1;i<=n;i++) cin>>arr[i];
    sort(arr+1,arr+1+n);
    for(int i=1,j=2;i<=n&&j<maxn;j++){
        while(p[j]>=arr[i]&&i<=n) {
            ans+=j;
            i++;
        }
    }
    printf("Case %d: ",time);
    cout<<ans<<" Xukha
";
}
int  main(){
    oula();
    ll t;
    cin>>t;
    for(ll i=1;i<=t;i++) solve(i);
    return 0;
}

我的思路和code2差不多,但是我的一直调不对。。。

用一个数组dp,记录每个幸运数字对应的长度的最小值。

对一个长度i,其对应的欧拉值。枚举小于当前欧拉值并且还没有赋值的(可能没有对应长度,或者对应长度在后边)欧拉值赋值长度i。这样可以保证当前欧拉值为j,dp[j]可以表示,大于等于j的欧拉值所对应的最小长度。

秒~~

code2:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll  maxn=1e6+10;
const ll N=1E6+20;
ll p[N];
ll arr[N];
ll dp[N];
void oula(){
    for(ll i=1;i<=maxn;i++) p[i]=i;
    for(ll i=2; i<=maxn; i+=2) p[i]/=2;
    for(ll i=3; i<=maxn; i+=2)
        if(p[i]==i){
            for(ll j=i; j<=maxn; j+=i)
                p[j]=(p[j]/i*(i-1));
        }
}
void solve(ll time){
    ll n;
    cin>>n;
    ll ans=0;
    for(ll i=1;i<=n;i++){
        ll x;
        cin>>x;
        ans+=dp[x];
    }
    printf("Case %d: %d Xukha
",time,ans);
}
int  main(){
    oula();
    memset(dp,0,sizeof dp);
    for(ll i=1;i<=maxn;i++){
        for(ll j=p[i];dp[j]==0&&j>=0;j--)
            dp[j]=i;
    }
    dp[1]=2;
    ll t;
    cin>>t;
    for(ll i=1;i<=t;i++) solve(i);
    return 0;
}
原文地址:https://www.cnblogs.com/Accepting/p/12524828.html