# [BZOJ3122] [Sdoi2013]随机数生成器

3
7 1 1 3 3
7 2 2 2 0
7 2 2 2 1

1
3
-1

### HINT

0<=a<=P-1,0<=b<=P-1,2<=P<=10^9

### 试题分析

#include<iostream>
#include<cstring>
#include<cstdio>
#include<map>
#include<cmath>
#include<algorithm>

using namespace std;
#define LL long long

LL x=0,f=1; char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
for(;isdigit(c);c=getchar()) x=x*10+c-'0';
return x*f;
}
const LL INF = 2147483600;
const LL MAXN = 100010;

LL T; LL P,A,B,C,X,t;
map<LL,LL> mp;

inline LL Pow(LL a,LL b){
LL res=1;
while(b){
if(b&1) res=res*a%P;
a=a*a%P; b>>=1;
} return res;
}
inline LL inv(LL x){
x=(x%P+P)%P;
return Pow(x,P-2)%P;
}

int main(){
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
while(T--){
if(X==t){printf("%d\n",1); continue;}
if(!A){if(B!=t) printf("%d\n",-1); else printf("%d\n",2); continue;}
if(A==1){if(!B) puts("-1"); else printf("%lld\n",(t-X+P)%P*inv(B)%P+1); continue;}
mp.clear(); LL k=(t+B*inv(A-1)%P)%P*inv(X+B*inv(A-1)%P)%P;
LL m=ceil(sqrt(P)); LL tmp=k;
mp[tmp]=1; for(LL i=1;i<=m;i++){
tmp=tmp*A%P; mp[tmp]=i+1;
} tmp=1; LL y=Pow(A,m); bool flag=false;
for(LL i=1;i<=m+1;i++){
tmp=tmp*y%P; LL pos=mp[tmp];
if(pos){
printf("%lld\n",i*m-pos+2); flag=true; break;
}
} if(!flag) puts("-1");
}
return 0;
}


posted @ 2018-08-25 12:10  wxjor  阅读(129)  评论(0编辑  收藏  举报