垃圾SDOI,,,,,,,,,,,,,,,
前2问快速幂之类的玩意乱搞
第三问,是一个看起来就nb的BSGS(baby step giant step)算法,大概的意思是把指数y分块(大小为m),y=am+b,然后把其中的am或b移动到z的一边,那么每一边都只需要算根号y次,复杂度就降低了。(根据费马小定理,y最大只能取到p-1,(否则会进入循环节))
因为移项之后指数是负的,所以求一下逆元,(真费事)
(真是个sb题,里面的int,LL,,,各种各样的不对,****,WA一片)
1 #include<bits/stdc++.h> 2 #define N 100005 3 #define LL long long 4 #define inf 0x3f3f3f3f 5 using namespace std; 6 inline LL ra() 7 { 8 LL x=0,f=1; char ch=getchar(); 9 while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();} 10 while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();} 11 return x*f; 12 } 13 int solve1(LL y,int z,int p) 14 { 15 y%=p; 16 LL ans=1; 17 for(int i=z;i;i>>=1,y=y*y%p) 18 if(i&1)ans=ans*y%p; 19 return ans; 20 } 21 void solve2(int y, int z, int p) 22 { 23 y%=p; 24 if (!y) {puts("Orz, I cannot find x!"); return; } 25 LL ans=(LL)solve1(y,p-2,p)*z%p; 26 printf("%d ",(int)ans%p); 27 } 28 map<int,int> mp; 29 void solve3(int y, int z, int p) 30 { 31 y%=p; 32 if (!y && !z) {puts("1"); return;} 33 if (!y) {puts("Orz, I cannot find x!"); return;} 34 mp.clear(); 35 LL m=ceil(sqrt(p)),t=1; 36 mp[1]=m+1; 37 for (LL i=1; i<m; i++) 38 { 39 t=t*y%p; 40 if (!mp[t]) mp[t]=i; 41 } 42 LL tmp=solve1(y,p-m-1,p),ine=1; 43 for (LL k=0; k<m; k++) 44 { 45 int i=mp[z*ine%p]; 46 if (i) 47 { 48 if (i==m+1) i=0; 49 printf("%lld ",k*m+i); 50 return; 51 } 52 ine=ine*tmp%p; 53 } 54 puts("Orz, I cannot find x!"); 55 } 56 int main() 57 { 58 int T=ra(), K=ra(); 59 while (T--) 60 { 61 LL y=ra(),z=ra(),p=ra(); 62 if (K==1) printf("%d ",solve1(y,z,p)); 63 if (K==2) solve2(y,z,p); 64 if (K==3) solve3(y,z,p); 65 } 66 return 0; 67 }