BZOJ3122 SDOI2013 随机数生成器 BSGS

题意:${x_{i + 1}} = (a{x_i} + b)\bmod p$,求最小的n使xn=t,无解输出-1,保证p为质数。

题解:

学好数理化,走遍天下都不怕

显然有\[{x_n} = {a^{n - 1}}{x_1} + b\sum\limits_{i = 0}^{n - 2} {{a^i}}  = {a^{n - 1}}{x_1} + \frac{{b({a^{n - 1}} - 1)}}{{a - 1}} \equiv t(\bmod p)\]

设a-1的逆元为c,代入整理后得到\[{a^{n - 1}} = (bc + t){({x_1} + bc)^{ - 1}}\bmod p\]

BSGS求a即可。注意有些特殊情况

①、x1==t的时候n=1

②、a==0的时候看b是否等于t

③、a==1的时候原式可以化为t=x1+(n-1)b,exgcd求解不解释

#include<map>
#include<cmath>
#include<cstdio>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;

int T;
ll p,a,b,x1,t;
map<ll,int> table;
map<ll,int>::iterator it;

ll exgcd(ll a,ll b,ll &x,ll &y){
    if(!b){
        x=1;y=0;
        return a;
    }

    ll tmp=exgcd(b,a%b,x,y),t=x;
    x=y,y=t-a/b*y;

    return tmp;
}
ll Quick_pow(ll a,ll b,ll p){
    a%=p;
    ll t=(b&1?a:1);

    while(b>>=1){
        a*=a,a%=p;
        if(b&1) t*=a,t%=p;
    }

    return t;
}

ll bsgs(ll A,ll B,ll C){
    table.clear();
    A%=C;

    if(!A){
        if(!B) return 1;
        else return -1;
    }

    ll m=ceil(sqrt(C)),t=1,tmp=1,x,y,ans=-1;

    for(int i=0;i<m;i++,t=(t*A)%p) table[t]=i;

    for(int i=0;i<m;i++){
        exgcd(tmp,C,x,y);

        x=((x*B)%C+C)%C;
        it=table.find(x);

        if(it!=table.end()){
            ans=i*m+it->second;
            break;
        }

        tmp=(tmp*t)%C;
    }

    if(ans==-1) return -1;
    return ans;
}

ll cal1(){
    ll C=(t-x1+p)%p,x,y,t=exgcd(b,p,x,y);

    if(C%t) return -1;
    C/=t;

    x=x*C%p;

    if(x<0) x+=p;
    return x+1;
}

ll cal2(){
    ll c=Quick_pow(a-1,p-2,p),A=(x1+b*c)%p,C=(t+b*c)%p,x,y,t=exgcd(A,p,x,y);

    if(C%t) return -1;

    C/=t;

    if(x<p) x=x%p+p;

    t=bsgs(a,x*C%p,p);

    if(t!=-1) return t+1;
    return -1;
}

ll solve(){
    if(x1==t) return 1;
    if(!a){
        if(b==t)return 2;
        return -1;
    }
    if(a==1) return cal1();
    return cal2();
}

int main(){
    cin >> T;
    while(T--){
        scanf("%d %d %d %d %d",&p,&a,&b,&x1,&t);
        cout << solve() << endl;
    }


    return 0;
}
View Code

 

posted @ 2017-02-26 12:28  WDZRMPCBIT  阅读(151)  评论(0编辑  收藏  举报