http://codeforces.com/problemset/problem/487/C 感觉是很糟糕的一个题...  首先,一个合法的构造,一定是开头是\(1\),结尾是\(N\),因为如果中间出现\(1\)或者\(N\)的话,一定会有重复。 然后我就觉得所有的合数都是不行的,因为任何的合数都可以拆成\(p \times q\),但是有的合数,只能拆成两个相同的数乘起来,比如\(4=2 \times 2\)、\(9=3 \times 3\),但是对于\(9\)来说,\(6\)中也存在\(3\),所以\(9\)还是不合法,于是合数中只有\(4\)需要特判,之后都不成立。 然后我们观察\((i+1)\times inv[i]\)这个式子。 因为\[(i+1)\times inv[i]=(j+1)\times inv[j]\] \[i \times j \times (i+1)\times inv[i]=i \times j \times (j+1)\times inv[j]\] \[j \times (i+1)=i \times (j+1)\]
上面的式子只有\(i=j\)时才成立。 于是\((i+1)\times inv[i]\)就会形成一个\(2\)到\(N-1\)的排列,这么构造就可以了。
| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 
 | #include<bits/stdc++.h>typedef long long LL;
 using namespace std;
 LL kpow(LL x,int y,int p)
 {
 if(y==0) return 1;
 LL w=kpow(x,y/2,p);
 w=w*w;
 w%=p;
 if(y%2) w*=x;
 w%=p;
 return w;
 }
 int n;
 int main()
 {
 scanf("%d",&n);
 if(n==4)
 {
 cout<<"YES"<<endl;
 cout<<1<<endl;
 cout<<3<<endl;
 cout<<2<<endl;
 cout<<4<<endl;
 return 0;
 }
 int bj=0;
 for(int i=2;i*i<=n;i++)
 {
 if(n%i==0)
 {
 cout<<"NO";
 return 0;
 }
 }
 printf("YES\n");
 printf("1\n");
 for(int i=2;i<n;i++)
 {
 LL ans=1;
 ans*=i;
 ans*=kpow(i-1,n-2,n);
 ans%=n;
 printf("%I64d\n",ans);
 }
 if(n!=1) printf("%d",n);
 return 0;
 }
 
 |