__int64 ago,there’s a heaven cow called sjy…
A god bull named wzc fell in love with her…
As an OI & MOer,wzc gave sjy a quesiton…
给定一个整数n,求一个整数m,满足m<=n,并且m/phi(m)的值最大。
注:phi(m)代表m的欧拉函数,即不大于m且与m互质的数的个数。
第一行是一个整数T,表示该测试点有T组数据。
接下来T行,每行一个整数n,意义如上所述。
输出一共T行,每行一个整数m。
若对于某个n,有不止一个满足条件的m,则输出最小的m。
1
10
6
对于10%的数据, n<=1000
对于30%的数据, n<=10^10
对于60%的数据, n<=10^2000
对于100%的数据,T<=100,n<=10^25000。
法一:数学方法
我们要求
法二:暴力打标找规律
首先打个暴力,找出1到一个较大但能在10秒内出解的数的所有答案,再找规律,注意要用实数类型,不能用整型(我就是在这里卡了好久,愣是没找到规律),最终改回来后一眼找出规律,这个规律好好找啊。
所以说,暴力要打对啊!
打个比较和高精乘就好了。
发现有多组数据,我们一开始给输入的数排一个序就好了。
常练离散大法好,危难来时把命保。
预处理出所有可能的答案,即2,2*3,2*3*5,2*3*5*7,…,然后每次O(n)找答案,或者二分找,速度没并有太大影响。
#include
#include
#include
#include
#include
#define ll long long
#define N 25200
#define MOD 100000000000000
using namespace std;
char st[N];
ll a[N],ans[6200][N/10],p[60000];
bool bz[60000];
ll t,len,s,k;
bool max(ll a[],ll b[]){
if(a[0]>b[0]) return 1;
if(b[0]>a[0]) return 0;
for(int i=a[0];i>=1;i--){
if(a[i]>b[i]) return 1;
if(a[i]return 0;
}
return 0;
}
ll length(ll x){
int l=0;
while(x>0){
x/=10;
l++;
}
return l;
}
int main(){
for(int i=2;i<=58880;i++){
if(!bz[i]){
p[++p[0]]=i;
for(int j=i;j<=58880/i;j++) bz[i*j]=1;
}
}
ans[0][0]=ans[0][1]=1;
for(int i=1;i<=p[0];i++){
ans[i][0]=ans[i-1][0];
for(int j=1;j<=ans[i][0];j++) ans[i][j]=ans[i-1][j]*p[i];
for(int j=1;j<=ans[i][0];j++){
ans[i][j+1]+=ans[i][j]/MOD;
ans[i][j]%=MOD;
}
while(ans[i][ans[i][0]+1]>0){
ans[i][0]++;
ans[i][ans[i][0]+1]+=ans[i][ans[i][0]]/MOD;
ans[i][ans[i][0]]%=MOD;
}
}
scanf("%d",&t);
while(t--){
scanf("%s",st+1);
len=strlen(st+1);
s=a[0]=0;k=1;
for(int i=1;i<=len;i++){
s+=(st[len-i+1]-'0')*k;
k*=10;
if(k==MOD){
a[++a[0]]=s;
s=0;k=1;
}
}
if(s>0) a[++a[0]]=s;
int l=0,r=p[0],mid=0,i=0;
while(l<=r){
mid=(l+r)/2;
if(max(ans[mid],a)) r=mid-1;
else{
l=mid+1;
i=l;
}
}
printf("%lld",ans[i-1][ans[i-1][0]]);
for(int j=ans[i-1][0]-1;j>=1;j--){
int x=length(ans[i-1][j]);
for(int k=1;k<=14-x;k++) printf("0");
printf("%lld",ans[i-1][j]);
}
printf("\n");
}
return 0;
}
#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");
}
}
作者:zsjzliziyang
QQ:1634151125
转载及修改请注明
本文地址:https://blog.csdn.net/zsjzliziyang/article/details/81366197