• 【BZOJ-3122】随机数生成器 BSGS


    3122: [Sdoi2013]随机数生成器

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 1362  Solved: 531
    [Submit][Status][Discuss]

    Description

    Input

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

    注意:P一定为质数

    Output

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

    Sample Input

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

    Sample Output

    1
    3
    -1

    HINT

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

    Source

    Solution

    不错的题

    对于题目中给出的式子,我们尝试的得出$X_{n}$关于$X_{1}$的式子

    显然暴力带是不能得到的,考虑对原始式子进行变形:首先同余方程式左右是可以同时+—*/的毫无问题,那么我们对式子如下变化:

    $X_{i+1}equiv aX_{i}+b (mod p)$

    ==>$X_{i+1}+frac{b}{a-1}equiv aX_{i}+b+frac{b}{a-1} (mod p)$
    ==>$X_{i+1}+frac{b}{a-1}equiv a(X_{i}+frac{b}{a-1}) (mod p)$

    那么我们显然能够用$X_{1}$表示$X_{n}$,层层带入得

    $X_{n}+frac{b}{a-1}equiv a^{n-1}(X_{1}+frac{b}{a-1}) (mod p)$

    然后在模意义下,我们使用逆元计算,这样的话,利用BSGS算法求解即可

    这里有些需要特判掉的情况:

    1° $X_{1}=t$ 显然ans=1

    2° $a==0$ 显然得到$X_{n}equiv b(mod p)$ 那么$b=t$时 ans=2 否则 ans=-1

    3° $a==1$ 显然得到$X_{n}equiv X_{1}+(n-1)b(mod p)$ 这样显然可以用ExGCD求解

    Code

    (感觉这是这道题最短的代码了2333)

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<map>
    using namespace std;
    long long read()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0' && ch<='9') {x=x*10+ch-'0';ch=getchar();}
        return (long long)x*f;
    }
    int T;
    long long p;
    long long Quick_Pow(long long x,long long y,long long p)
    {
        long long re=1;
        for (int i=y; i; i>>=1,x=x*x%p)
            if (i&1) re=re*x%p;
        return re;
    }
    long long BSGS(long long a,long long b,long long p)
    {
        long long m=ceil(sqrt(p)),t=1;
        map<long long,long long>hash;
        for (int i=0; i<=m; i++,b=b*a%p) hash[b]=i;
        long long f=Quick_Pow(a,m,p);
        for (long long i=1; i<=m; i++)
            if (t=t*f%p,hash.count(t)) return i*m-hash[t]+1;
        return -1;
    }
    int main()
    {
        T=read();
        while (T--)
            {
                long long a,b,X1,t;
                p=read(),a=read(),b=read(),X1=read(),t=read();
                if (X1==t) {puts("1"); continue;}
                if (a==0) {if (t==b) puts("2"); else puts("-1"); continue;}
                if (a==1) {if (!b) puts("-1"); else printf("%lld
    ",((((t-X1+p)%p)*Quick_Pow(b,p-2,p)%p)%p)+1); continue;}
                long long aa=Quick_Pow(a-1,p-2,p),t1=b*aa%p,t2=(X1%p+t1)%p,tt=Quick_Pow(t2,p-2,p),t3=(t+t1)%p;
                printf("%lld
    ",BSGS(a,t3*tt%p,p));
            }
        return 0;
    }
  • 相关阅读:
    HTML5实现音频播放
    百度编辑器UEditor常用设置函数大全
    .Net一般处理程序来实现用户名的验证
    软件设计师13-数据库设计
    软件设计师12-数据流图
    百度云BCC安装WordPress镜像
    Java获取客户端真实IP地址
    软件设计师11-面向对象技术
    百度云BCC主机宝镜像
    软件设计师10-系统开发模型
  • 原文地址:https://www.cnblogs.com/DaD3zZ-Beyonder/p/5721732.html
Copyright © 2020-2023  润新知