1 条题解

  • 0
    @ 2026-8-18 10:06:33

    本题解同步发表在博客

    老实了,22 分钟秒掉的思路,55 分钟写好的代码,结果调了 3030 分钟。

    首先题解的所有运算均在模 PP 的情况下进行。

    分析题目,定义 f(x)=Ax+Bf(x)=Ax+B,题目即求最小的 xx 满足 fx(S)=Gf^x(S)=G

    先打表:

    f(S)=AS+Bf(S)=AS+B f2(S)=A2S+AB+Bf^2(S)=A^2S+AB+B ...... fx(S)=AxB+i=0x1AiBf^x(S)=A^xB+\sum_{i=0}^{x-1} A^iB

    那么非常容易就可以得到:

    fx+1(S)fx(S)=Ax+1S+AxBAxSf^{x+1}(S)-f^x(S)=A^{x+1}S+A^xB-A^xS

    又得知 f(G)G=AG+BGf(G)-G=AG+B-G

    代入 G=fx(S)G=f^x(S) 得:

    Ax+1S+AxBAxS=AG+BGA^{x+1}S+A^xB-A^xS=AG+B-G

    即:

    Ax(AS+BS)=AG+BGA^x(AS+B-S)=AG+B-G

    AS+BSAS+B-S 移到右边,得:

    Ax=AG+BGAS+BSA^x=\frac{AG+B-G}{AS+B-S}

    右边部分可以用逆元解决,然后聪明的小朋友就去用 BSGS 了,喜提 00 分。连样例都过不去

    这是为什么呢?

    因为 BSGS 只能解决 A>1A > 1 的情况。所以 A=0A=0 得直接特判,A=1A=1 用 exgcd。

    好了,现在有 33 分了。因为会出现 AS+BS=0AS+B-S=0 的情况,你还得特判。

    最后就可以过了。

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    int bsgs(int a,int b,int p)
    {
    	a%=p,b%=p;if(b==1)return 0;
    	int m=ceil(sqrt(p)),am=1;
    	unordered_map<int,int>f;
    	for(int i=1;i<=m;i++)f[b*(am=am*a%p)%p]=i;
    	for(int i=1,t=1;i<=m;i++)if(f.count(t=t*am%p))return i*m-f[t];
    	return -1;
    }
    void exgcd(int a,int b,int &d,int &x,int &y)
    {
    	if(b==0){d=a,x=1,y=0;return;}
    	exgcd(b,a%b,d,y,x);
    	y-=a/b*x;
    }
    int qpow(int a,int b,int p){int ans=1;for(;b;b>>=1,a=a*a%p)if(b&1)ans=ans*a%p;return ans;}
    void solve()
    {
    	int p,a,b,s,g;cin>>p>>a>>b>>s>>g;
    	if(a==0)
    	{
    		if(s==g)cout<<0<<'\n';
    		else if(b==g)cout<<1<<'\n';
    		else cout<<-1<<'\n';
    		return ;
    	}
    	if(a==1)
    	{
    		int d,x,y,K=((g-s)%p+p)%p;
    		exgcd(b,p,d,x,y);
    		if(K%d!=0)cout<<-1<<'\n';
    		else
    		{
    			int dx=abs(p/d);
    			x=(x*(K/d)%dx+dx)%dx;
    			cout<<x<<'\n';
    		}
    		return;
    	}
    	int p1=((a*g+b-g)%p+p)%p,p2=((a*s+b-s)%p+p)%p;
    	if(p1==0&&p2==0)cout<<0<<'\n';
    	else if(p1!=0&&p2==0)cout<<-1<<'\n';
    	else
    	{
    		int ans=bsgs(a,(p1)%p*qpow(p2,p-2,p)%p,p);
    		cout<<ans<<'\n';
    	}
    }
    signed main()
    {
    	int t;cin>>t;
    	while(t--)solve();
    	return 0;
    }
    
    • 1

    信息

    ID
    10024
    时间
    4000ms
    内存
    1024MiB
    难度
    10
    标签
    递交数
    8
    已通过
    2
    上传者