zoukankan      html  css  js  c++  java
  • bzoj 3122: [Sdoi2013]随机数生成器【BSGS】

    题目要求的是:

    [...a(a(a(ax+b)+b)+b)+b...=a^nx+a^{n-1}b+a^{n-2}b+...+bequiv t(mod p) ]

    后面这一大坨看着不舒服,所以考虑把它化掉,这里有两种做法:

    做法一:两边同乘a-1

    [(a^{n-1}x)(a-1)+b(a^{n-1}-1)equiv t(a-1)(mod p) ]

    [a^nx-a^{n-1}x+ba^{n-1}-b equiv at-t(mod p) ]

    [axa^{n-1}-xa^{a-1}+ba^{n-1} equiv at-t+b(mod p) ]

    [(ax-x+b)a^{n-1} equiv at-t+b(mod p) ]

    [a^{n-1}equiv (at-t+b)inv(ax-x+b)(mod p) ]

    注意这个很容易乘爆,记得随时取模

    做法二:后面乘上a-1的逆元

    [a^{n-1}x+b(a^{n-1}-1)inv(a-1)equiv t(mod p) ]

    [a^{n-1}x+b*a^{n-1}*inv(a-1)-b*inv(a-1)equiv t(mod p) ]

    [a^{n-1}x+b*a^{n-1}*inv(a-1)equiv t+b*inv(a-1)(mod p) ]

    [a^{n-1}(b*inv(a-1)+x)equiv t+b*inv(a-1)(mod p) ]

    [a^{n-1}equiv (t+b*inv(a-1))inv(b*inv(a-1)+x)(mod p) ]

    然后用BSGS解即可,记得加一

    #include<iostream>
    #include<cstdio>
    #include<map>
    #include<cmath>
    using namespace std;
    long long T,p,a,b,x,t,y,z;
    map<long long,long long>mp;
    long long ksm(long long a,long long b)
    {
    	long long r=1ll;
    	a%=p;
    	while(b)
    	{
    		if(b&1)
    			r=r*a%p;
    		a=a*a%p;
    		b>>=1;
    	}
    	return r;
    }
    int main()
    {
    	scanf("%lld",&T);
    	while(T--)
    	{
    		scanf("%lld%lld%lld%lld%lld",&p,&a,&b,&x,&t);
    		if(x==t)
    		{
    			puts("1");
    			continue;
    		}
    		if(a==0)
    		{
    			if(b==t)
    				puts("2");
    			else
    				puts("-1");
    			continue;
    		}
    		if(a==1&&b==0)
    		{
    			puts("-1");
    			continue;
    		}
    		if(a==1)
    		{
    			long long now=ksm(b,p-2);
    			printf("%lld
    ",(((t-x)%p+p)%p*now%p+p)%p+1);
    			continue;
    		}
    		y=a,z=((a*t%p-t+b)%p*ksm(a*x-x+b,p-2)%p+p)%p;
    		//y=a,z=((t+b*ksm(a-1,p-2)%p)%p*ksm((x%p+b*ksm(a-1,p-2)%p)%p,p-2))%p;//(a*t-t+b)*ksm(a*x-x+b,p-2);做法二
    		y%=p;
    		if(!y&&!z)
    		{
    			puts("1");
    			continue;
    		}
    		if(!y)
    		{
    			puts("-1");
    			continue;
    		} 
    		mp.clear();
    		long long m=ceil(sqrt(p)),t=1;
    		mp[1]=m+1;
    		for(long long i=1;i<m;i++)
    		{
    			t=t*y%p;
    			if(!mp[t])
    				mp[t]=i;
    		}
    		long long tmp=ksm(y,p-m-1),now=1,f=0;
    		for(long long k=0;k<m;k++)
    		{
    			long long i=mp[z*now%p];
    			if(i) 
    			{
    				if(i==m+1)
    					i=0;
    				printf("%lld
    ",k*m+i+1);
    				f=1;
    				break;
    			}
    			now=now*tmp%p;
    		}
    		if(!f)
    			puts("-1");
    	}
    	return 0;
    }
    
  • 相关阅读:
    Binary Search Tree Iterator 解答
    Invert Binary Tree 解答
    Min Stack 解答
    Trapping Raining Water 解答
    Candy 解答
    Jump Game II 解答
    Implement Hash Map Using Primitive Types
    Gas Station 解答
    Bucket Sort
    HashMap 专题
  • 原文地址:https://www.cnblogs.com/lokiii/p/8360164.html
Copyright © 2011-2022 走看看