第一场1007(BSGS)

2021“MINIEYE杯”中国大学生算法设计超级联赛(1)1007 Pass! hdu6956

There are n players passing ball on the football field.

Initially, the first player has the ball. Then each second, the player with ball should pass the ball to any other player.

Alice wonders how many way to pass the ball, such that after t seconds, the ball will turn back to the first player. So she asks Bob for help.

Now, Bob solved the question and found that the answer modulo 998244353 is x. But he forgot the exact number of t. So he ask you for help, to find the smallest non-negative integer t, such that the answer of Alice's question modulo 998244353 will be x.

可以求出

\[f_i=(n-2)f_{i-1}+(n-1)f_{i-2} \]

\[f_{t}=a^t \]

带入上式得

\[a^2=(n-2)a+(n-1) \]

解得其两个不同得特征值为

\[\begin{cases}a_1=n-1\\a_2=-1\end{cases} \]

所以有

\[f_t=A(n-1)^{t}+B(-1)^{t} \]

由题意可得

\[\begin{cases}f_0=1\\f_1=0\end{cases} \]

所以

\[\begin{cases}A+B=1\\A(n-1)-B=0\end{cases} \]

解得

\[\begin{cases}A=\frac{1}{n}\\B=\frac{n-1}{n}\end{cases} \]

所以

\[f_t=\frac{(n-1)^{t}+(n-1)(-1)^{t}}{n} \]

当t为偶数时

\[f_t=\frac{(n-1)^{t}+(n-1)}{n} \]

此时要求最小的t使得

\[\frac{(n-1)^t+(n-1)}{n}\equiv x\quad(mod\quad998244353) \]

移项得

\[(n-1)^t\equiv nx-(n-1)\quad(mod\quad998244353) \]

当t为奇数时

\[f_t=\frac{(n-1)^{t}-(n-1)}{n} \]

此时要求最小的t使得

\[\frac{(n-1)^t-(n-1)}{n}\equiv x\quad(mod\quad998244353) \]

移项得

\[(n-1)^t\equiv nx+(n-1)\quad(mod\quad998244353) \]

BSGS求解

#include <bits/stdc++.h>
using namespace std;
const int mod=998244353;
struct Hash{
	static const int MOD=233333;
	static const int maxn=1e6+5;
	int tot,head[MOD+10],next[maxn],h[maxn],val[maxn];
	inline void clear(){tot=0;memset(head,0,sizeof(head));}
	inline void insert(int H,int VAL)
	{
		for(int i=head[H%MOD];i;i=next[i])
		if(h[i]==H){
			val[i]=VAL;return;
		}
		h[++tot]=H;val[tot]=VAL;next[tot]=head[H%MOD];head[H%MOD]=tot;
	}
	inline int count(int H)
	{
		for(int i=head[H%MOD];i;i=next[i])if(h[i]==H)return val[i];
		return 0;
	}
}q;
//unordered_map<int,int>q;//较慢10倍左右 
int gcd(int a,int b)
{
    if(b==0)return a;
    return gcd(b,a%b);
}
int ksm(int a,int b)
{
    int res=1;
    while(b)
    {
        if(b&1)res=1ll*res*a%mod;
        a=1ll*a*a%mod;
        b>>=1;
    }
    return res;
}
int bsgs(int y,int z)
{
    q.clear();
    int cnt=0;
    int m=sqrt(mod),t=1;
//    for(int i=gcd(y,mod);i!=1;i=gcd(y,mod))//exbsgs处理当mod与y不互质时
//    {
//        if(z%i){
//            return -1;
//        }
//        cnt++;mod/=i;z/=i;t=t*y/i%mod;
//        if(z==t)
//        {
//            return cnt;
//        }
//    }
    int s=z,ans=-1;
    for(int i=0;i<m;i++)//从0~m-1枚举右边 
    {
//    	q[s]=i;
        q.insert(s,i);
        s=1ll*s*y%mod;
    }
    int xx=ksm(y,m);s=t;
    for(int i=1;i<=m+1;i++)
    {
        s=1ll*s*xx%mod;
        if(q.count(s))
        {
            ans=i*m-q.count(s)+cnt;
            break;
        }
    }
    return ans;
//    if(ans==-1)cout<<"No Solution\n";
//    else cout<<ans<<"\n";
}
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,x;
        cin>>n>>x;
        if(x==1)
        {
            printf("0\n");continue;
        }
        int ans=2e9;
        int m=bsgs(n-1,((1ll*n*x-(n-1))%mod+mod)%mod);
        if(m&1||m==-1);
        else ans=min(ans,m);
        m=bsgs(n-1,((1ll*n*x+(n-1))%mod+mod)%mod);
        if(m&1&&m!=-1)ans=min(ans,m);
        if(ans==2e9)ans=-1;
        printf("%d\n",ans);
    }
    return 0;
}
posted @ 2021-07-20 22:25  1427314831a  阅读(121)  评论(0编辑  收藏  举报