gmoj 6832. 2020.10.24【NOIP Improve Group A】world solution

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)}2k1(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;
}

Guess you like

Origin blog.csdn.net/huangzihaoal/article/details/109320191
Recommended