zoukankan      html  css  js  c++  java
  • bzoj3122: [Sdoi2013]随机数生成器

    3122: [Sdoi2013]随机数生成器

    Description

    Input

    输入含有多组数据,第一行一个正整数T,表示这个测试点内的数据组数。  
    接下来T行,每行有五个整数p,a,b,X1,t,表示一组数据。保证X1和t都是合法的页码。 
    注意:P一定为质数
    

    Output

    共T行,每行一个整数表示他最早读到第t页是哪一天。如果他永远不会读到第t页,输出-1。
    

    HINT

    $ 0 \leqslant a \leqslant P-1,0 \leqslant b \leqslant P-1,2 \leqslant P \leqslant 10^9 $

    BSGS裸题

    把线性递推式转化为通项公式为

    \( x[n] = x1 \* A^{n-1} + \frac {B*A^{n-1}} {A-1} = t \)

    移项,得:

    \( (x1 + \frac {B} {A-1}) \* A^{n-1} = t - \frac {B} {A-1} \)

    但是有几种情况要特判

    \(t = x1\)时,输出1

    当$a = 0 $时,看t与b是否相等

    当$a = 1 $时,由于等比数列公比不确定也要特判,判一下exgcd就行了

    剩下的BSGS就可以了

    #include<bits/stdc++.h>
    using namespace std;
    #define REP(i,st,ed) for(register int i=st,i##end=ed;i<=i##end;++i)
    #define DREP(i,st,ed) for(register int i=st,i##end=ed;i>=i##end;--i)
    typedef long long ll;
    inline int read(){
        int x;
        char c;
        int f=1;
        while((c=getchar())!='-' && (c>'9' || c<'0'));
        if(c=='-') c=getchar(),f=-1;
        x=c^'0';
        while((c=getchar())>='0' && c<='9') x=(x<<1)+(x<<3)+(c^'0');
        return x*f;
    }
    inline ll readll(){
        ll x;
        char c;
        int f=1;
        while((c=getchar())!='-' && (c>'9' || c<'0'));
        if(c=='-') c=getchar(),f=-1;
        x=c^'0';
        while((c=getchar())>='0' && c<='9') x=(x<<1ll)+(x<<3ll)+(c^'0');
        return x*f;
    }
    map<int,int> mp;
    int ksm(int x,int y,int mod){
        int res=1;
        while(y){
            if(y&1) res=1ll*res*x%mod;
            x=1ll*x*x%mod;
            y>>=1;
        }
        return res;
    }
    int exgcd(int &x,int &y,int a,int b){
        if(!b){
            x=1,y=0;
            return a;
        }
        int res=exgcd(y,x,b,a%b);
        y-=a/b*x;
        return res;
    }
    int solve(int a,int b,int c,int mod){
        int x,y;
        int res=exgcd(x,y,a,b);
        if(c%res) return -1;c/=res;
        x=(x%mod+mod)%mod;
        return 1ll*x*c%mod;
    }
    int bsgs(int A,int B,int mod){
        mp.clear();
        int m=(int)sqrt(mod)+1,inv=ksm(A,m,mod);
        inv=ksm(inv,mod-2,mod);
        mp[1]=m+1;
        for(int i=1,x=A;i<m;++i,x=1ll*x*A%mod)
            if(!mp[x]) mp[x]=i;
        for(int i=0;i*m<mod;++i){
            int x=mp[B];
            if(x) return i*m+x%(m+1);
            B=1ll*B*inv%mod;
        }
        return -1;
    }
    int main(){
        int T=read();
        while(T--){
            int p=read(),A=read(),B=read(),x1=read(),t=read();
            if(x1==t){
                printf("1\n");
                continue;
            }
            x1%=p;
            if(A==0){
                if(B==t) printf("2\n");
                else printf("-1\n");
                continue;
            }
            if(A==1){
                int x=solve(B,p,(t-x1+p)%p,p);
                if(x==-1) printf("-1\n");
                else printf("%d\n",x+1);
                continue;
            }
            int u=1ll*B*ksm(A-1,p-2,p)%p;
            int x=solve((u+x1)%p,p,(t+u)%p,p);
            if(x==-1) printf("-1\n");
            else{
                x=bsgs(A,x,p);
                if(x==-1) printf("-1\n");
                else printf("%d\n",x+1);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    Medium | LeetCode 11. 盛最多水的容器 | 双指针
    Hard | LeetCode 41. 缺失的第一个正数 | 原地Hash
    Navicat Premium 15 使用注册机破解,附带Navicat Premium 15安装包、注册机下载
    vue $forceUpdate() 强制重新渲染
    js 原生录制屏幕
    mysql 8.0.17 解压版安装教程
    vue 移动端适配 amfe-flexibl
    mysql重置密码
    2059-Authentication plugin'caching_sha2_password'cannot be loaded
    用js实现时间减去前1小时、7天、1月、1年
  • 原文地址:https://www.cnblogs.com/zhou888/p/8481580.html
Copyright © 2011-2022 走看看