Test Instructions:Link
Method:Bsgs+ Matrix Inversion
parsing:The problem is to A x =B(mod c ) A and B are replaced by matrices. But there is no change anywhere else. So it involves the inverse of the matrix. How do you find the inverse of a matrix? First, after the original matrix followed by a unit matrix, it is advisable to set the right diagonal first to Gaussian elimination of the original matrix and to eliminate the strict right diagonal of the form of the unit matrix. Then the unit matrix is calculated at the same time as the elimination element, and the last unit matrix becomes its inverse matrix. This problem guarantees that the matrix has inverse but the case that there is no inverse matrix is Gaussian elimination. So judgment should be judged. In addition, just measured the data, about the matrix hash, directly take the lower right corner of the value on the line. Too weak for data
Code:
#include <map>#include <cmath>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define N#define M 140345#define BASE 0using namespace Std;intN,p;struct matrix{int MapN [N];} A,b,ret;struct node{intFrom,to,Next;intVal;} edge[m+Ten];intcnt,head[m+Ten];void init () {memset (head,-1, sizeof (head)); Cnt=1;} void Edgeadd (intFromintTo,intval) {edge[cnt].from=from,edge[cnt].to=to,edge[cnt].val=val; EDGE[CNT].Next=head[from]; head[from]=cnt++;} Matrix Mul (Matrix A,matrix b) {memset (ret.Map,0, sizeof (ret.Map)); for(intI=1; i<=n;i++) for(intj=1; j<=n;j++) for(intk=1; k<=n;k++) ret.MapI [J]= (Ret.MapI [J]+a.MapI K*b.MapK [j])%p;returnRET;}intQuick_my (int x,int y){intret=1; while(y) {if(y&1) ret= (ret*x)%p;x=(x*x)%p;y>>=1; }returnRET;}intHash (Matrixx){return x.MapN [n];} Matrix GET_INV (Matrixx) {memset (ret.Map,0, sizeof (ret.Map)); for(intI=1; i<=n;i++) ret.MapI [i]=1; for(intI=1; i<=n;i++) {intchose=-1; for(intj=i;j<=n;j++)if(x.Map[j] [i]!=0) {chose=j; Break;} //if(chose==-1) //return-1There is no solution to my brain complement should be like this. for(intj=1; j<=n;j++) Swap (x.MapI [j],x.Map[Chose] [j]), swap (ret.MapI [J],ret.Map[Chose] [j]);intInv=quick_my (x.MapI [i],p-2); for(intj=1; j<=n;j++) {x.MapI [j]=x.MapI [j]*INV%p; Ret.MapI [J]=ret.MapI [j]*INV%p; } for(intj=1; j<=n;j++) {if(I==J)Continue;intPre=x.Map[j] [i];//Be sure to record in advance or it will definitely affect the answer, because this value is changed =-= I am also a brain remnant. for(intk=1; k<=n;k++) {x.Map[j] [K]= (x.Map[j] [K]-pre*x.MapI [K])%p+P)%p; Ret.Map[j] [K]= (Ret.Map[j] [K]-pre*ret.MapI [K])%p+P)%p; } } }returnRet }intBSGS (Matrix A,matrix B,intC) {init ();int m=(int) Ceil (sqrt(C)); Matrix tmp; memset (TMP.Map,0, sizeof (TMP.Map)); for(intI=1; i<=n;i++) tmp.MapI [i]=1; for(intI=0;i<m; i++) {intHashtmp=hash (TMP);intflag=1; for(intJ=head[hashtmp%M];j!=-1; J=edge[j].Next)if(edge[j].val==hashtmp) {flag=0; Break;}if(flag) Edgeadd (hashtmp%M, i,hashtmp); Tmp=mul (Tmp,a); } Matrix INV=GET_INV (TMP); for(intI=0; i<=m; i++) {intHashb=hash (B); for(intJ=head[hashb%M];j!=-1; J=edge[j].Next)if(EDGE[J].VAL==HASHB)returnI*m+edge[j].to; B=mul (B,INV); }return-1;}intMain () {scanf ("%d%d", &n,&p); for(intI=1; i<=n;i++) for(intj=1; j<=n;j++) scanf ("%d", &a.MapI [j]); for(intI=1; i<=n;i++) for(intj=1; j<=n;j++) scanf ("%d", &b.MapI [j]);printf("%d\ n", Bsgs (A,b,p));}
Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced.
Bzoj 4128 matrix bsgs+ matrices Inversion