topic
https://gmoj.net/senior/#main/show/6832
answer
For this question, I found that the position of simulation 1 can be changed, and then I hit a 40-point scale. But then I can’t think of it...
It can be found that the number at the i-th position will go to 2 imod (n + 1) 2i\mod (n+1) after one transformation2 imod(n+1 ) , then 1 will be at2 kmod (n + 1) 2^k\mod (n+1)after k times2kmod(n+1 ) , if 1 returns to 1, then there will be 2 k ≡ 1 (mod (n + 1)) 2^k\equiv 1\pmod{(n+1)}2k≡1(mod(n+1 ) )
If n is the smallest k, then n is legal.
According to Euler’s theorem , a φ (m) ≡ 1 (modm), gcd (a, m) = 1 a^{\varphi(m)}\equiv 1\pmod{m}\quad,\gcd(a, m)=1aφ ( m )≡1(modm),gcd(a,m)=1得 2 φ ( n + 1 ) ≡ 1 ( m o d ( n + 1 ) ) 2^{\varphi(n+1)}\equiv 1\pmod{(n+1)} 2φ ( n + 1 )≡1(mod(n+1))
If n+1 is not a prime number, φ (n + 1) <n \varphi(n+1)< nφ ( n+1)<n , so n+1 is a prime number.
But at this time, n is not necessarily the smallest k, and violent enumeration and judgment are needed, and it will not pass.
Consider optimization. Because when n is not the minimum k, 1 must be rotated several cycles, and the minimum cycle length must be a factor of n, so other multiples of this factor will also satisfy the condition.
Decompose n into prime factors, let n = ∏ piqin=\prod p_i^{q_i}n=∏piqi, If n is not the smallest k, then there must be npi \frac{n}{p_i}pinTo meet the conditions.
Because the number of different prime factors of a number is less than or equal to 8, so you can pass this question.
CODE
#include<cstdio>
using namespace std;
typedef long long ll;
#define N 10000005
int pri[700005],p[N];bool b[N];
inline int pow(int x,int y,int p)
{
int s=1;
while(y)
{
if(y&1) s=1LL*s*x%p;
x=1LL*x*x%p,y>>=1;
}
return s;
}
int main()
{
freopen("world.in","r",stdin);
freopen("world.out","w",stdout);
ll sum=0;int A,tmp,j;
scanf("%d",&A);
for(int i=2;i<N;++i)
{
if(!b[i]) pri[++pri[0]]=i,p[i]=i;
for(int j=1;j<=pri[0]&&i*pri[j]<N;++j)
{
b[i*pri[j]]=1,p[i*pri[j]]=pri[j];
if(i%pri[j]==0) break;
}
}
for(int i=2;i<=A;++i) if(!b[i+1])
{
tmp=i;
while(tmp>1)
{
j=p[tmp];
if(pow(2,i/j,i+1)==1) break;
while(tmp%j==0) tmp/=j;
}
if(tmp==1) sum+=i;
}
A>>=1,printf("%.5LF\n",sum/(long double)A);
return 0;
}