欧拉函数有关式ϕ(n)/(n-1)值递减序列性质

来源:互联网 发布:log4j 只输出sql 编辑:程序博客网 时间:2024/05/21 22:33

欧拉函数有关式 ϕ(n)/(n-1)值的递减序列性质

昨天vijos上有个模拟赛,T2比较有趣。

上题

描述

欧拉函数 \phi(n)ϕ(n) 统计了 11 到 nn 中与 nn 互素的数字个数,例如 \phi(9)=6ϕ(9)=6

现在给定正整数 AA 和 BB,请找出最小的正整数 nn 满足 \frac{\phi(n)}{n-1} < \frac{A}{B}n1ϕ(n)<BA

格式

输入格式

输入只有一行,是两个正整数 AA 和 BB,满足 1\le A<B\le 10^61A<B106

输出格式

输出一个正整数,表示最小满足条件的 nn

样例1

样例输入1

1 2
Copy

样例输出1

6
Copy

样例2

样例输入2

2 5
Copy

样例输出2

12
Copy

限制

对于 20\%20% 的数据,保证答案不超过 10^7107

对于 30\%30% 的数据,保证答案不超过 2.5\times 10^{8}2.5×108

对于 40\%40% 的数据,保证答案不超过 7\times 10^{9}7×109

对于 50\%50% 的数据,保证答案不超过 2.5\times 10^{11}2.5×1011

对于 60\%60% 的数据,保证答案不超过 3.5\times 10^{14}3.5×1014

对于 70\%70% 的数据,保证答案不超过 1.5\times 10^{16}1.5×1016

对于 80\%80% 的数据,保证答案不超过 7\times 10^{17}7×1017

对于 90\%90% 的数据,保证答案不超过 3.5\times 10^{30}3.5×1030

对于 100\%100% 的数据,保证答案不超过 10^{200}10200

每一组数据的时限为 11 秒。


这题数据范围一脸不可做的样子= =
于是我们考虑找规律(emmmm不要问我为啥找规律因为我只会找规律qwqwqwqwqwq)
由于题目要求找最小的n,我们运用贪心的思想,找该函数值的递减序列。
我们先从1开始枚举,找10000以内的递减序列

于是我们发现这个数列有不断迭代的特点,即
for(i=r;;i+=r)
if(ϕ(n)==ϕ(n-r))r=i;
于是我们尝试验证,对比两个程序的结果

我们再扩展到100000

这个规律似乎是对的qwq,而且效率特别高
于是昨天我就这么做了非高精的部分

T2得了80分
今天上午我又尝试找了一下迭代位置n值的关系
nϕ(n) (n-1)/ϕ(n)

又发现了神奇的质数序列
我这个蒟蒻正在尝试利用这个规律A掉这道题qwq
附上找规律的两个程序
1:
#include<cstdio>
long long m;
long double c=10; 
long long phi(long long n)
{
    long long ans,i,k;
    if(n==1) 
        ans=1;
    else
{        
      ans=n;
      k=1;
      for(i=2;n!=1;i+=k)
 {
        if(n%i==0)
{
ans/=i;
            ans*=(i-1);
            while(n%i==0) n/=i;
            i=k;
        }
      }
    }
    return ans;
}
int main()
{
for(long long i=1;i<100000;++i)
{
m=phi(i);
if(m/1.0/(i-1)<c)c=m/1.0/(i-1),
printf("%lld      %lld      %llf\n",i,m,m/1.0/(i-1));
}
return 0;
}
2:
#include<cstdio>
long long m,r;
long double c=1; 
long long phi(long long n)
{
    long long ans,i,k;
    if(n==1) 
        ans=1;
    else
{        
      ans=n;
      k=1;
      for(i=2;n!=1;i+=k)
 {
        if(n%i==0)
{
ans/=i;
            ans*=(i-1);
            while(n%i==0) n/=i;
            i=k;
        }
      }
    }
    return ans;
}
int main()
{
r=1;
for(long long i=r;i<100000;i+=r)
{
m=phi(i);
if(if(i-r>0)&&m==phi(i-r)) r=i;
printf("%lld      %lld      %llf\n",i,m,m/1.0/(i-1));
}
return 0;
}
再附上80分迭代:
#include<cstdio>
long long r,m,a,b;
long double c;
long long phi(long long n)
{
    long long ans,i,k;
    if(n==1) 
        ans=1;
    else
{        
      ans=n;
      k=1;
      for(i=2;n!=1;i+=k)
 {
        if(n%i==0)
{
ans/=i;
            ans*=(i-1);
            while(n%i==0) n/=i;
            i=k;
        }
      }
    }
    return ans;
}
int main()
{
r=1;
scanf("%lld%lld",&a,&b);
c=a/1.0/b;
for(long long i=r;i>0;i+=r)
{
m=phi(i);
if(i-r>0&&m==phi(i-r)) r=i,
if(c>m/1.0/(i-1))
{
printf("%lld",i);
return 0;
}
}
return 0;
}
啊对了,每次迭代(r的值改变)时,n的值与上一次迭代的值的商成质数序列
有关的数学证明等我学完高中数学吧qwq,作为高一新生的我积累还太少啊