牛客小白月赛14 -A (找规律+除数取模)
题目链接:https://ac.nowcoder.com/acm/contest/879/A
题意:有n个城市,编号1~n,k天,第一天位于城市1,要求最后一天在城市1,且相邻两天不在同一个城市,求方案数。
思路:设k天后在城市1的方案数为f(k),前k-1天每天有n-1种选择,最后一天必须去城市1,即有(n-1)^(k-1)种可能,但是这包括了倒数第二天在城市1的情况。但我们会发现倒数第二天在城市1的方案数即f(k-1),即f(k)=(n-1)^(k-1)-f(k-1)。
不访列举前几项:
f(k=1)=0
f(k=2)=n-1
f(k=3)=(n-1)^2-f(k=2)=(n-1)^2-(n-1)
f(k=4)=(n-1)^3-f(k-3)=(n-1)^3-(n-1)^2+(n-1)
可以发现每一项均是等比数列的求和等式。于是有f(k)=[(-1)k*(n-1)+(n-1)k]/n。
要将这个式子对MOD=998244353取模,需要用到公式a/b%m=a%(b*m)/b。
AC代码:
#include<cstdio> using namespace std; typedef long long LL; const LL MOD =998244353; LL n,k,M; LL qmul(LL a,LL b){ LL ret=0; while(b){ if(b&1) ret=(ret+a)%M; a=(a+a)%M; b>>=1; } return ret; } LL qpow(LL a,LL b){ LL ret=1; while(b){ if(b&1) ret=qmul(ret,a); a=qmul(a,a); b>>=1; } return ret; } int main(){ scanf("%lld%lld",&n,&k); M=n*MOD; if(k&1) printf("%lld\n",(M-n+1+qpow(n-1,k))%M/n); else printf("%lld\n",(n-1+qpow(n-1,k))%M/n); return 0; }
朋友们,无论这个世界变得怎样,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。