Description
加里敦大学有一个龙舟队,龙舟队有n支队伍,每只队伍有m个划手,龙舟比赛是一个集体项目,和每个人的能力息息相关,但由于龙舟讲究配合,所以评价队伍的能力的是一个值c = (b1*b2...*bm)/(a1*a2...*am),其中bi表示第i个位置标准能力值,ai表示在队伍中第i个位置的划手的能力值。最 后通过约分,我们会得到c= B/A,其中gcd(B,A)=1,即A, B是互质的,
但是由于比赛现场的情况不一样,我们认为在现场压力为M的情况下,队伍最后的表现情况认为是C=1(mod M)我们规定在模M的条件下1/x = y,其中y满足xy=1(mod M)并且y是大于等于0,并且小于M的值,如果不存在这 样的y我们就认为在M的条件下这支队伍会发挥失常(即y是x在模M意义下的逆元,如果不存在逆元我们认为队伍发挥失常)。现在是这个赛季的比赛安排情况,现在教练组想知道各队的在比赛中表现情况。
Input
第一行输入三个个整数n, m,k,表示有n支队伍,每支队伍有m个人组成,有k场比赛
第二行输入m个整数,第i个表示表征第i个位置的标准能力值为bi
第3行到第n +2行,共n行,每行有m个数,第2+i行第j个数表示第i支队伍的 第j个位置的划手的能力值
第n + 3行到第n + k + 2行,共n行,每行有两个数x,M,分别表示第x支队伍 会在压力为M的比赛中出战
Output
共k行,第i行表示在第i个参赛安排种队伍的现场表现情况C,如果出现队伍发挥失常,输出“-1”
Sample Input
5 2 3
3 2 3
2 3 2
1 4
2 4
1 7
Sample Output
-1
4
HINT
对于20%的数据,1<M,ai,bi<10^8,m<=100
对于100%的数据,1<M,ai,bi<2*10^8,m<=10000,n<=20,k<=50
Solution
$Pollard-Rho$。
首先对于每次询问,先把$M$质因数分解一下,然后在分子和分母上分别用那些质因数去分解,并且开个桶存一下质因子的出现情况。如果分解完某个质因子在分母上还存在(也就是桶中的个数为负数),那显然$M$和分母不互质,无解输出$-1$。
否则就可以用$exgcd$把逆元给解出来,然后输出就好了QwQ
Code
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<map> 5 #include<algorithm> 6 #define N (10009) 7 #define LL long long 8 using namespace std; 9 10 LL n,m,k,x,y,c,M,cnt,ans,inv; 11 LL a[21][N],b[N],Num[N],Keg[N]; 12 LL prime[15]={2,3,5,7,11,13,17,19,23}; 13 14 LL Mul(LL a,LL b,LL MOD) 15 { 16 LL tmp=a*b-(LL)((long double)a*b/MOD+0.1)*MOD; 17 return tmp<0?tmp+MOD:tmp; 18 } 19 20 LL Qpow(LL a,LL b,LL MOD) 21 { 22 LL ans=1; 23 while (b) 24 { 25 if (b&1) ans=Mul(ans,a,MOD); 26 a=Mul(a,a,MOD); b>>=1; 27 } 28 return ans; 29 } 30 31 LL gcd(LL a,LL b) {return b==0?a:gcd(b,a%b);} 32 33 void exgcd(LL a,LL b,LL &x,LL &y) 34 { 35 if (!b) {x=1; y=0; return;} 36 exgcd(b,a%b,y,x); y-=x*(a/b); 37 } 38 39 bool Miller_Rabin(LL n) 40 { 41 if (n==2) return 1; 42 if (n<2 || n%2==0) return 0; 43 LL m=n-1,l=0; 44 while (m%2==0) m>>=1,l++; 45 for (int i=0; i<9; ++i) 46 { 47 LL p=prime[i],w=Qpow(p,m,n); 48 if (w==1 || w==n-1 || p==n) continue; 49 for (int j=1; j<=l; ++j) 50 { 51 LL u=Mul(w,w,n); 52 if (u==1 && w!=1 && w!=n-1) return 0; 53 w=u; 54 } 55 if (w!=1) return 0; 56 } 57 return 1; 58 } 59 60 LL Pollard_Rho(LL n,LL c) 61 { 62 LL x=rand()%n,y=x,p=1,k=2; 63 for (int i=1; p==1; ++i) 64 { 65 x=(Mul(x,x,n)+c)%n; 66 p=x>y?x-y:y-x; 67 p=gcd(p,n); 68 if (i==k) y=x, k+=k; 69 } 70 return p; 71 } 72 73 void Solve(LL n) 74 { 75 if (n==1) return; 76 if (Miller_Rabin(n)) {Num[++cnt]=n; return;} 77 LL t=n; 78 while (t==n) t=Pollard_Rho(n,rand()%(n-1)+1); 79 Solve(t); Solve(n/t); 80 } 81 82 int main() 83 { 84 scanf("%lld%lld%lld",&n,&m,&k); 85 for (int i=1; i<=m; ++i) 86 scanf("%lld",&b[i]); 87 for (int i=1; i<=n; ++i) 88 for (int j=1; j<=m; ++j) 89 scanf("%lld",&a[i][j]); 90 while (k--) 91 { 92 for (int i=1; i<=cnt; ++i) Keg[i]=0; 93 cnt=0; ans=1; inv=1; 94 scanf("%lld%lld",&x,&M); 95 Solve(M); 96 sort(Num+1,Num+cnt+1); 97 cnt=unique(Num+1,Num+cnt+1)-Num-1; 98 for (int i=1; i<=m; ++i) 99 { 100 LL tmp=b[i]; 101 for (int j=1; j<=cnt; ++j) 102 while (tmp%Num[j]==0) Keg[j]++, tmp/=Num[j]; 103 ans=Mul(ans,tmp,M); 104 } 105 for (int i=1; i<=m; ++i) 106 { 107 LL tmp=a[x][i]; 108 for (int j=1; j<=cnt; ++j) 109 while (tmp%Num[j]==0) Keg[j]--, tmp/=Num[j]; 110 inv=Mul(inv,tmp,M); 111 } 112 bool flag=true; 113 for (int i=1; i<=cnt; ++i) 114 if (Keg[i]<0) flag=false; 115 if (!flag) {puts("-1"); continue;} 116 for (int i=1; i<=cnt; ++i) 117 if (Keg[i]) ans=Mul(ans,Qpow(Num[i],Keg[i],M),M); 118 exgcd(inv,M,x,y); inv=(x%M+M)%M; 119 printf("%lld ",Mul(ans,inv,M)); 120 } 121 }