题解 P3599 【Koishi Loves Construction】

oscar

2020-06-05 23:10:38

Solution

**Task 1:** $> 1$ 的奇数无解,$1$ 的解显然 偶数的一种可行解为 $0,1,-2,3,-4,\cdots,n-1$ 把 $\leq 0$ 的数 $+n$ 即可 **Task 2:** 我想不出来官方题解那么妙的构造怎么办? 可以转化为Task1解决。 $>4$ 的合数无解,$1,2,4$ 的解显然 对于奇质数的情况根据某定理恰有 $\varphi(n-1)$ 个原根,(通过随机+暴力判定可以较高效地)任取一个原根,设其为 $g$ 将 $g^0,g^1,\cdots,g^{n-2}$ 一一映射到 $0,1,\cdots,n-2$ 即可转化为 $n'=n-1$ 版本的Task1(显然 $n-1$ 是偶数) 在以上结果的结尾添加一个 $n$ 就是Task2的一种构造 代码 ```cpp #include<bits/stdc++.h> using namespace std; int ty,T,n; std::mt19937 ran; int pw[111111],fl[111111];//pw存原根的幂 bool ok(int g)//暴力检验是否为原根 { memset(fl,0,sizeof(fl)); pw[0]=1;fl[1]=1; for(int i=1;i<n-1;i++) { pw[i]=1ll*pw[i-1]*g%n; if(fl[pw[i]])return false; fl[pw[i]]=1; } return true; } int main() { ios_base::sync_with_stdio(false); ran.seed(0); cin>>ty>>T; while(T--) { cin>>n; if(ty==1) { if(n==1)cout<<"2 1"<<endl; else if(n%2==0) { cout<<2<<' '<<n; for(int i=1;i<n;i++)cout<<' '<<(i%2?i:n-i); cout<<endl; } else cout<<0<<endl; } else { if(n==1)cout<<"2 1"<<endl; else if(n==2)cout<<"2 1 2"<<endl; else if(n==4)cout<<"2 1 3 2 4"<<endl; else { int zz=1;//是否质数 for(int i=2;i*i<=n;i++) { if(n%i==0) { zz=0; break; } } if(!zz)cout<<0<<endl; else { int g=ran()%(n-1)+1; while(!ok(g))g=ran()%(n-1)+1; cout<<2<<' '<<pw[0]; for(int i=1;i<n-1;i++)cout<<' '<<(i%2?pw[i]:pw[n-1-i]); cout<<' '<<n<<endl; } } } } return 0; } ```