【NOIP2013模拟】Heaven Cow与God Bull

Description

给定一个整数n,求一个整数m,满足m<=n,并且m/phi(m)的值最大。
注:phi(m)代表m的欧拉函数,即不大于m且与m互质的数的个数。

Solution

方法

要求

MAX(mφ(m))m

我们知道 φ(m)=mp|mp1p
那么代入ans
MAX(1p|mp1p)m

分子最小时,分母不变,分数最大,所以要求的是
MIN(p|mp1p)m

因为p都是质数,而且除了 φ(1),φ(1) 都是小于1的,所以越乘越小,所以把2,3,5,7,11…..直到快爆掉n位置后,这个数就是满足要求的数了。

要打高精度

打个比较和高精乘就好了。

离散大法

发现有多组数据,我们一开始给输入的数排一个序就好了。
常练离散大法好,危难来时把命保。

Code

#include
#include
#include
#include
#include
#define fo(i,a,b) for(i=a;i<=b;i++)
#define fod(i,a,b) for(i=a;i>=b;i--)
typedef int arr[25005]; 
using namespace std;
int i,j,k,l,t,n,m,tt,zhi[100007],tot;
int ans1[101][25005];
arr ans,b,c;
bool bz[1000007];
char s[25005];
struct node{
    arr shu;
    int o;
}a[101];
bool bijiao(arr x,arr y){
    int i,j,k,l;
    if(x[0]>y[0]){
        return 0;
    }
    else if(x[0]==y[0]){
        fod(i,x[0],1){
            if(x[i]>y[i]){   
                return 0;
            }
            else if (x[i]return 1;
        }
        return 0;
    } 
}
bool cmp(node x,node y){
    return bijiao(x.shu,y.shu);    
}
void cheng(int x){
    int i,j,k,l,o=0;
    memset(b,0,sizeof(b));
    fo(i,1,ans[0]){
        b[i]=b[i]+ans[i]*x+o;
        b[i+1]+=b[i]/10;
        b[i]=b[i]%10;
    }
    for(b[0]=ans[0];b[b[0]+1];){
        b[++b[0]+1]+=b[b[0]]/10;
        b[b[0]]=b[b[0]]%10;
    }
}
void work(int x){
    int i,j,k,l;
    fo(i,tot,zhi[0]){
        l=i;
        cheng(zhi[i]);
        if(bijiao(a[x].shu,b))break; 
        memcpy(ans,b,sizeof(ans));
    } 
    memcpy(ans1[a[x].o],ans,sizeof(ans1[a[x].o]));
    tot=l;   
}
int main(){
    scanf("%d",&t);
    fo(j,1,t){
        scanf("%s",s+1);
        tt=strlen(s+1);
        a[j].shu[0]=tt;
        a[j].o=j;
        fo(i,1,tt)a[j].shu[tt-i+1]=s[i]-'0';
    }
    sort(a+1,a+1+t,cmp);
    n=1000000;
    fo(i,2,trunc(sqrt(n))){
        if(!bz[i]){
            fo(j,2,n/i){
                bz[i*j]=1;
            }
        }
    }
    fo(i,2,n)if(!bz[i])zhi[++zhi[0]]=i;
    tot=1;ans[0]=ans[1]=1;
    fo(i,1,t){work(i);
        work(i);
    }
    fo(i,1,t){
        fod(j,ans1[i][0],1)printf("%d",ans1[i][j]);
        printf("\n");
    }
}

你可能感兴趣的:(数论,离线大法)