首页 > 其他 > 详细

[SDOI2013] 随机数生成器

时间:2020-07-03 18:29:15      阅读:52      评论:0      收藏:0      [点我收藏+]

题意:

给定$a,b,p,x_1$,$\forall i>1,x_i = ax_{i-1} +b$。

求最小的$i$满足$x_i = t$,若无解则输出-1。

$0\leq a,b,x_1 , t<p\leq 10^{9},p是质数$。

 

题解:

挺水的一道题,展开之后BSGS即可。

但$a\leq 1$的地方需要特判,还巨复杂,有高中数学题内味了。

复杂度$O(\sqrt{p})$。

 

套路:

  • 推式子时:注意特判整体乘除0的情况。

 

代码:

技术分享图片
#include<bits/stdc++.h>
#define maxn 200005
#define maxm 500005
#define inf 0x7fffffff
#define ll long long
#define rint register int
#define debug(x) cerr<<#x<<": "<<x<<endl
#define fgx cerr<<"--------------"<<endl
#define dgx cerr<<"=============="<<endl

using namespace std;
ll p; unordered_map<ll,ll> M;

inline ll read(){
    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;
}

inline ll pw(ll a,ll b){ll r=1;while(b)r=(b&1)?r*a%p:r,a=a*a%p,b>>=1;return r;}
inline ll inv(ll x){return pw(x,p-2);}

inline ll BSGS(ll a,ll b){
    M.clear(); ll n=ceil(sqrt(p)),ans=1ll<<62;
    for(ll i=0,t=1;i<=n;i++,t=t*a%p) M[b*t%p]=i;
    for(ll i=0,t=1,w=pw(a,n);i<=n;i++,t=t*w%p)
        if(M[t] && i*n-M[t]>=0) ans=min(ans,i*n-M[t]);
    if(ans==(1ll<<62)) return -1;
    else return ans;
}

int main(){
    //freopen("P3306_2.in","r",stdin);
    //freopen("1.out","w",stdout);
    ll T=read();
    while(T--){
        p=read(); ll a=read(),b=read(),x1=read(),t=read();
        if(a==0){
            if(x1==t) printf("1\n");
            else if(b==t) printf("2\n");
            else printf("-1\n");
        }
        else if(a==1){
            if(b==0){
                if(x1==t) printf("1\n");
                else printf("-1\n");
            }
            else printf("%lld\n",(t-x1+p)*inv(b)%p+1);
        }
        else{
            if((x1+(b*inv(a-1)))%p==0){
                if((t+(b*inv(a-1)))%p==0) printf("1\n");
                else printf("-1\n");
            }
            else{
                ll y=(t+(b*inv(a-1)))%p*inv((x1+(b*inv(a-1)))%p)%p;
                ll ans=BSGS(a,y)+1;
                if(ans==0) printf("-1\n"); 
                else printf("%lld\n",ans);
            }
        }
    }
    return 0;
}
//59 38 24 25 5
随机数生成器

 

[SDOI2013] 随机数生成器

原文:https://www.cnblogs.com/YSFAC/p/13231571.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!