zoukankan      html  css  js  c++  java
  • 「Luogu3306」[SDOI2013]随机数生成器

    「Luogu3306」[SDOI2013]随机数生成器

    problem

    Solution

    我们来回忆一下数列递推公式求通项的方法

    (Y_i=X_i+frac{b}{a-1}),则有

    [Y_i=aY_{i-1}Rightarrow Y_i=a^{i-1}Y_1 ]

    于是题目转化为求解方程

    [t+frac b{a-1}equiv a^{x-1}(X_1+frac b{a-1})pmod p ]

    [Rightarrow a^{x-1}equivfrac{t+frac b{a-1}}{X_1+frac b{a-1}}pmod p ]

    好的,这个东西我们只要用BSGS就可以了

    End?


    几个细节:

    (X_1=t)时,直接输出(1)

    (a=0)时,输出若(b=t)则输出(2),否则无解,(X_1=t)的情况已经特判

    (a=1)时,方程实际上为

    [(x-1)bequiv t-X_1pmod p ]

    根据裴蜀定理判掉无解,然后直接算(x-1)即可

    需要注意的是如果(frac{t-X_1} b=p),则不需要取模直接输出

    True End

    Code

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    #include <iostream>
    #include <map>
    #define mp(x,y) (make_pair((x),(y)))
    #define inv(x) (fastpow((x),p-2))
    using namespace std;
    typedef long long ll;
    
    template <typename T>void read(T &t)
    {
    	t=0;int f=0;char c=getchar();
    	while(!isdigit(c)){f|=c=='-';c=getchar();}
    	while(isdigit(c)){t=t*10+c-'0';c=getchar();}
    	if(f)t=-t;
    }
    
    int T;
    
    ll p,a,b,X1,t;
    ll m;
    
    ll fastpow(ll a,ll b)
    {
    	ll re=1,base=a;
    	while(b)
    	{
    		if(b&1)
    			re=re*base%p;
    		base=base*base%p;
    		b>>=1;
    	}
    	return re;
    }
    
    map<ll,ll> rec;
    void Pre()
    {
    	rec.clear();
    	ll tmp=1;
    	for(register int i=0;i<m;++i,tmp=tmp*a%p)
    		rec.insert(mp(tmp,i));
    }
    
    ll BSGS()
    {
    	ll iatm=inv(fastpow(a,m)),tmp=1;
    	for(register int i=0;i<m;++i,tmp=tmp*iatm%p)
    		if(rec.find(b*tmp%p)!=rec.end())
    			return i*m+rec[b*tmp%p];
    	return -2;
    }
    
    ll gcd(ll a,ll b)
    {
    	return b?gcd(b,a%b):a;
    }
    
    int main()
    {
    	read(T);
    	while(T--)
    	{
    		read(p),read(a),read(b),read(X1),read(t);
    		if(X1==t)
    		{
    			puts("1");
    			continue;
    		}
    		if(a==1)
    		{
    			t=(t-X1+p)%p;
    			if(t%gcd(b,p))
    				puts("-1");
    			else
    				printf("%lld
    ",t*inv(b)+1==p?p:(t*inv(b)+1)%p);
    			continue;
    		}
    		if(a==0)
    		{
    			printf("%lld
    ",b==t?2:-1ll);
    			continue;
    		}
    		b=b*inv(a-1)%p;
    		b=(t+b)*inv(X1+b)%p;
    		m=ceil(sqrt(p));
    		Pre();
    		printf("%lld
    ",BSGS()+1);
    	}
    	return 0;
    }
    
  • 相关阅读:
    相对路径与绝对路径总结
    java.lang.ClassNotFoundException: org.apache.commons.dbutils.ResultSetHandle
    navicat建立本地连接出错解决
    JSP基础知识补充
    新建ASPX页面,并练习div布局和table布局
    .net和ASP.net,c#的区别
    char、varchar、nchar、nvarchar四种类型
    WebContent下新建目录放入jsp,跳转servlet页面出错解决
    设计模式(4)----抽象工厂模式
    设计模式(3)----工厂方法模式
  • 原文地址:https://www.cnblogs.com/lizbaka/p/10656151.html
Copyright © 2011-2022 走看看