Pass!
题意:
nnn个人,最开始,第一个人拿球。每秒每个人可以把球传给任意一个其他人。ttt秒过后,球回到第一个人的传球序列方案数取模998244353998244353998244353后为xxx。给nnn和xxx求满足条件最小的ttt。
思路:
由于最后一秒要回到第一个人,那么时间为ttt的时候,球在111手上。由于不能传球给自己,那么时间为t−1t-1t−1的时候,球肯定在x(x≠1)x(x\neq 1)x(x=1)手上。
设ttt秒的时候,方案数为f(t)f(t)f(t)。
我们可以讨论时间为t−2t-2t−2的时候,球有可能在111手上,也有可能在其他人手上。
- 如果球在111手上,那么就相当于时间在t−2t-2t−2的时候就传回111的方案数f(t−2)f(t-2)f(t−2),再乘上下一步可能传给除111以外的其他人人数n−1n-1n−1。
- 如果球在x(x≠1)x(x\neq 1)x(x=1)手上,那么就相当于在t−1t-1t−1的时候的方案的倒数第二步和最后一步之间加上一步,这一步可能传给除111和xxx之外的其余n−2n-2n−2个人。
所以我们可以得到通向公式:f(t)=(n−2)f(t−1)+(n−1)f(t−2)f(t)=(n-2)f(t-1)+(n-1)f(t-2)f(t)=(n−2)f(t−1)+(n−1)f(t−2)。
通过特征方程,我们设f(t)−xf(t−1)=s(f(t−1)−xf(t−2))f(t)-xf(t-1)=s(f(t-1)-xf(t-2))f(t)−xf(t−1)=s(f(t−1)−xf(t−2))。
可得:{s+x=n−2−sx=n−1\left\{\begin{aligned}s+x=n-2\\-sx=n-1\end{aligned}\right.{s+x=n−2−sx=n−1
消元sss得:x2−(n−2)x−(n−1)=0x^2-(n-2)x-(n-1)=0x2−(n−2)x−(n−1)=0。
解方程:
∵Δ=b2−4ac=n2\because\Delta=b^2-4ac=n^2∵Δ=b2−4ac=n2
∴x1=n−1,x2=−1\therefore x_1=n-1,x_2=-1∴x1=n−1,x2=−1
所以可以得到通项公式方程f(t)=A(n−1)t+B(−1)tf(t)=A(n-1)^t+B(-1)^tf(t)=A(n−1)t+B(−1)t。
又{f(0)=A+B=1f(1)=A(n−1)+B(−1)=0\left\{\begin{aligned}f(0)&=A+B=1\\f(1)&=A(n-1)+B(-1)=0\end{aligned}\right.{f(0)f(1)=A+B=1=A(n−1)+B(−1)=0
解,得:{A=1nB=n−1n\left\{\begin{aligned}A&=\cfrac{1}{n}\\B&=\cfrac{n-1}{n}\end{aligned}\right.⎩⎪⎪⎨⎪⎪⎧AB=n1=nn−1
所以可以得到通项公式f(t)=(n−1)t+(n−1)⋅(−1)tnf(t)=\cfrac{(n-1)^t+(n-1)\cdot(-1)^t}{n}f(t)=n(n−1)t+(n−1)⋅(−1)t。
就将问题化成了求f(t)≡xmod Pf(t)\equiv x \mod Pf(t)≡xmodP的解。
将f(t)f(t)f(t)分奇偶讨论,可以得到:
{[(n−1)2]x≡nx−(n−1)t=2x[(n−1)2]x≡nxn−1+1t=2x+1\begin{cases}[(n-1)^2]^x\equiv nx-(n-1) &t=2x \\ [(n-1)^2]^x\equiv \cfrac{nx}{n-1}+1&t=2x+1\end{cases}⎩⎨⎧[(n−1)2]x≡nx−(n−1)[(n−1)2]x≡n−1nx+1t=2xt=2x+1
可以采用解ax≡bmod Pa^x\equiv b\mod Pax≡bmodP的BSGS算法求解。
因为有点卡常,所以用unordered_map,并且移一下相,减少一次求解次数。
代码:
#pragma GCC optimize(2)
#include<iostream>
#include<math.h>
#include<unordered_map>
#define int long long
const int N=1e6+10;
const int mod=998244353;
const int inf=0x3f3f3f3f;
const double eps=1e-8;
const double pi=acos(-1);
const double INF=1e18;
using namespace std;
int qpow(int a,int b)
{
int ans=1;
while(b)
{
if(b&1)
ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
int M=sqrt(mod)+1;
unordered_map<int,int> m;
signed main()
{
int T;
scanf("%lld",&T);
while(T--)
{
int n,x;
scanf("%lld%lld",&n,&x);
int b1=(n*x-(n-1)+mod)%mod,b2=(n*x%mod*qpow(n-1,mod-2)%mod+1)%mod;
int a=(n-1)*(n-1)%mod;
m.clear();
if(b1==1)
{
puts("0");
continue;
}
if(b2==1)
{
puts("1");
continue;
}
int p=1,f=0,i;
for(i=0;i<M;i++)
{
m[p]=i;
p=p*a%mod;
}
b1=qpow(b1,mod-2);
b2=qpow(b2,mod-2);
int tt=qpow(a,M),t=tt;
for(i=1;i<=M+1;i++)
{
if(m[t*b1%mod])
{
printf("%lld\n",2*(i*M-m[t*b1%mod]));
f=1;
break;
}
if(m[t*b2%mod])
{
printf("%lld\n",2*(i*M-m[t*b2%mod])+1);
f=1;
break;
}
t=t*tt%mod;
}
if(f==0)
puts("-1");
}
return 0;
}