zoukankan      html  css  js  c++  java
  • 「BZOJ 3122」「SDOI2013」 随机数生成器

    Description

    Description

    Hint

    (p in [2,10^9]) 且为质数。

    保证 (X_1)(t) 都是合法的页码。

    Solution

    根据递推关系,得:

    [X_2 equiv a cdot X_1 + b pmod p ]

    [X_3 equiv a cdot X_2 + b equiv a^2 cdot X_1 + ab + b pmod p ]

    [X_4 equiv a cdot X_3 + b equiv a^3 cdot X_1 + a^2b + ab + b pmod p ]

    [cdots cdots ]

    [X_n equiv a^{n-1} cdot X_1 + b imes sumlimits_{i=0}^{n-2} a^i pmod p ]

    我们发现 (sum_{i=0}^{n-2} a^i) 就是一个等比数列求和,那么:

    [X_n equiv a^{n-1} cdot X_1 + b imes dfrac{1 - a^{n-1}}{1 - a} pmod p ]

    [X_n equiv a^{n-1} cdot X_1 - dfrac{a^{n-1}}{1 - a} + dfrac{b}{1 - a} pmod p ]

    [X_n equiv a^{n-1} cdot (X_1 - dfrac{1}{1 - a}) + dfrac{b}{1 - a} pmod p ]

    [a^{n-1} cdot (X_1 - dfrac{1}{1 - a}) equiv X_n - dfrac{b}{1 - a} pmod p ]

    [a^{n-1} equiv dfrac{X_n - dfrac{b}{1 - a}}{X_1 - dfrac{1}{1 - a}} pmod p ]

    而这个 (X_n) 其实就是题目中的 (t) ,那么我们就是要求关于 (n) 方程

    [a^{n-1} equiv dfrac{t - dfrac{b}{1 - a}}{X_1 - dfrac{1}{1 - a}} pmod p ]

    的这些非负整数解(如果有解的话)。

    我们惊喜地发现这里只有 (n) 一个未知数,那么显然可以用 BSGS (这里 (p) 为质数)求解。

    但这里还有不少需要注意的细节:

    • (t = X_1) 时,答案为 (0)
    • (a = 0) 时,(X_i equiv b pmod p),其中 (i > 1)
    • (a = 1) 时,(X_i equiv b(i-1) pmod p),那么这就是一个线性同余方程,直接求逆元即可。

    注意式子中的所有除法都是逆元。

    /*
     * Author : _Wallace_
     * Source : https://www.cnblogs.com/-Wallace-/
     * Problem : BZOJ 3122 SDOI2013 随机数生成器
     */
    #include<cmath>
    #include<iostream>
    #include<tr1/unordered_map>
    
    typedef long long LL;
    typedef std::tr1::unordered_map<LL,LL> HashMap;
    using std::cin;
    using std::cout;
    using std::endl;
    
    LL fastpow(LL a,LL b,LL c) {
    	if(!b) return 1ll%c;
    	LL t=fastpow(a,b>>1,c);
    	if(b&1) return t*t%c*a%c;
    	else return t*t%c;
    }
    
    LL inverse(LL a,LL p) {
    	return fastpow(a,p-2,p);
    }
    
    HashMap f;
    inline LL BSGS(LL a,LL b,LL p) {
    	f.clear();
    	LL m=ceil(sqrt(p));
    	b%=p;
    	for(LL i=1;i<=m;i++)
    		(b*=a)%=p,f[b]=i;
    	LL t=fastpow(a,m,p);
    	b=1;
    	for(LL i=1;i<=m;i++) {
    		(b*=t)%=p;
    		if(f.count(b))
    			return (i*m-f[b]+p)%p;
    	}
    	return -1;
    }
    
    signed main() {
    	LL p,a,b,x1,t;
    	int Test_c;
    	cin>>Test_c;
    	while(Test_c--) {
    		cin>>p>>a>>b>>x1>>t;
    		if(x1==t) {
    			cout<<1<<endl;
    		} else if(a==0) {
    			if(b==t) cout<<2<<endl;
    			else cout<<-1<<endl;
    		} else if(a==1) {
    			if(b==0) cout<<-1<<endl;
    			else cout<<((t-x1)%p+p)%p*inverse(b,p)%p+1<<endl;
    		} else {
    			LL tmp=((b*inverse(a-1,p)%p+t)%p)%p*inverse((b*inverse(a-1,p)%p+x1)%p,p)%p;
    			LL ans=BSGS(a,tmp,p);
    			if(ans==-1) cout<<-1<<endl;
    			else cout<<ans+1<<endl;
    		}
    	}
    }
    
  • 相关阅读:
    oracle 锁表查看与解锁
    oracle 监视索引是否使用
    oracle 查看数据库版本
    mybatis 中文做参数报错
    windows mysql绿色版配置
    maven使用本地jar包
    Java 使用Jedis连接Redis数据库(-)
    Linux 安装redis
    ELK之在CentOS7.5上使用rpm包安装配置ELK7版本
    Ubuntu-18.04更改安装源为国内源
  • 原文地址:https://www.cnblogs.com/-Wallace-/p/12608686.html
Copyright © 2011-2022 走看看