2021杭電多校第二場1010(找規律,快速乘)
阿新 • • 發佈:2021-08-23
2021杭電多校第二場1010(找規律,快速乘)
Problem - 6970 (hdu.edu.cn)
思路:
通過打表,可以得出獲得的序列一定是一個長度為p-1的排列
令這個排列為\(\pi\),排列的第i個數為\(\pi(i)\),排列的逆序對數為\(n(\pi)\),計\(sgn(\pi)=(-1)^{n(\pi)}\)
很明顯\(sgn(\pi)=\frac{\prod_{0<i<j\le p-1}\pi(i)-\pi(j)}{\prod_{0<i<j\le p-1}i-j}=\prod_{0<i<j\le p-1}\frac{\pi(i)-\pi(j)}{i-j}\)
由本題中的定義\(\pi(i)=ia\ (mod\ p)\)
\(\prod_{0<i<j\le p-1}\frac{\pi(i)-\pi(j)}{i-j}=\prod_{0<i<j\le p-1}\frac{ai-aj}{i-j}=a^{\frac{p(p-1)}{2}}\equiv a^{\frac{p}{2}}\ (mod\ p)\)
這裡我個人認為按費馬小定理化出來的結果是\(a^{\frac{p}{2}}\),但官方題解這裡給了\(a^{\frac{p-1}{2}}\)(可能是為了湊二次剩餘的形式看起來好看?),但由於題目保證p為一個奇素數,所以\(\frac{p}{2}=\frac{p-1}{2}\)
然後我們只需要計算\(a^{\frac{p}{2}}\ (mod\ p)\) 即可判斷\(n(\pi)\)的奇偶
注意\(1\le a,p\le 1e18\)中間需要用到快速乘,但樸素的快速乘會T,題解這裡貌似用到了什麼黑科技
#include<bits/stdc++.h> using namespace std; long long mod; long long mul(long long a,long long b) { long long res=0; while(b) { if(b&1) { res=(res+a); if(res>=mod)res-=mod; } a=(a<<1); if(a>=mod)a-=mod; b>>=1; } return res; } inline long long Mul(long long x,long long y){ long long tmp=(x*y-(long long)((long double)x/mod*y+1.0e-8)*mod); return (tmp+mod)%mod; } long long ksm(long long a,long long b) { long long res=1; while(b) { if(b&1)res=Mul(res,a); a=Mul(a,a); b>>=1; } return res; } int main() { int t; scanf("%d",&t); while(t--) { long long a; scanf("%lld%lld",&a,&mod); if(ksm(a,(mod)/2)==1)puts("0"); else puts("1"); } return 0; }