[BJOI2019] 勘破神机

题意:

记$F(n,k)$为用$1\times 2$的小方格填满$k$个$2\times n$的网格且每个网格的填充方案均不相同的方案数;

记$G(n,k)$为用$1\times 2$的小方格填满$k$个$3\times n$的网格且每个网格的填充方案均不相同的方案数。

给定$l,r,k$,你需要求出$ans2=\frac{1}{r-l+1}{\sum \limits_{n=l}^{r}{F(n,k)}}$或$ans3=\frac{1}{r-l+1}{\sum \limits_{n=l}^{r}{G(n,k)}}$。

$l,r\leq 10^{18},k\leq 501$。

 

题解:

考虑$F(n)$的递推式,发现就是斐波那契数列。

利用待定系数法解出通项$F(n)=\frac{\sqrt{5}}{5}[(\frac{1+\sqrt{5}}{2})^{n+1}-(\frac{1-\sqrt{5}}{2})^{n+1}]$。

而本题中所求$F(n,k)$实际上就是$F(n)\choose k$。

那么就可以开始推式子了,所求式为

$\sum \limits_{n=l}^{r}F(n,k)=\sum \limits_{n=l}^{r}{F(n)\choose k}=\sum \limits_{n=l}^{r}{\frac{F(n)^{\underline{k}}}{k!}}$

用第一类斯特林数将下降幂转成正常幂,得到

$=\frac{1}{k!} \sum \limits_{n=l}^{r}{\sum \limits_{i=0}^{k}{(-1)^{k-i}\begin{bmatrix} k \\ i \end{bmatrix}F(n)^{i}}}$

$=\frac{1}{k!} \sum \limits_{i=0}^{k}{(-1)^{k-i}\begin{bmatrix} k \\ i \end{bmatrix} \sum \limits_{n=l}^{r}{F(n)^{i}}}$

将右边的$F(n)$用二项式定理展开,在这里我们令$A=\frac{\sqrt{5}}{5},B=-\frac{\sqrt{5}}{5},x=\frac{1+\sqrt{5}}{2},y=\frac{1-\sqrt{5}}{2}$,则有

$=\frac{1}{k!} \sum \limits_{i=0}^{k}{(-1)^{k-i}\begin{bmatrix} k \\ i \end{bmatrix} \sum \limits_{n=l}^{r}{\sum \limits_{j=0}^{i}{{i\choose j}[(Ax)^{j}(By)^{(i-j)}]^{n+1}}}}$

$=\frac{1}{k!} \sum \limits_{i=0}^{k}{(-1)^{k-i}\begin{bmatrix} k \\ i \end{bmatrix} \sum \limits_{j=0}^{i}{{i\choose j}\sum \limits_{n=l}^{r}{[(Ax)^{j}(By)^{(i-j)}]^{n+1}}}}$

将有关$n$的项使用等比数列求和公式即可在$O(k^{2}\log{n})$的复杂度内求解。

考虑$G(n)$的递推式,发现当$n$为奇数时无解,那么我们令$G'(n)=G(2n)$。

手画一下,发现恰好填满2列时有3种方案,而填满多于2列时都只有2种方案,则有

$G'(n)=3 G'(n-1)+\sum \limits_{i=0}^{n-2}{2 G'(i)}$

$G'(n-1)=3 G'(n-2)+\sum \limits_{i=0}^{n-3}{2 G'(i)}$

用上式减下式,得到

$G'(n)-G'(n-1)=3G'(n-1)-G'(n-2)$

$G'(n)=4G'(n-1)-G'(n-2)$

将上面的$F(n)$替换成$G'(n)$再做一遍即可。

 

套路:

  • 推式子时:注意边界条件。
  • 推式子时:由不熟悉的形式转化为熟悉的形式。

 

代码:

#include<bits/stdc++.h>
#define maxn 1005
#define maxm 500005
#define inf 0x7fffffff
#define mod 998244353
#define ll long long
#define rint register ll
#define debug(x) cerr<<#x<<": "<<x<<endl
#define fgx cerr<<"--------------"<<endl
#define dgx cerr<<"=============="<<endl

using namespace std;
ll S[maxn][maxn],C[maxn][maxn],fac[maxn],ifac[maxn];
struct vc{
    ll x,y,z;
    vc operator+(const vc b){vc res;res.x=(x+b.x)%mod;res.y=(y+b.y)%mod,res.z=z;return res;}
    vc operator-(const vc b){vc res;res.x=(x-b.x+mod)%mod;res.y=(y-b.y+mod)%mod,res.z=z;return res;}
    vc operator*(const vc b){vc res;res.x=(x*b.x%mod+z*y*b.y%mod)%mod;res.y=(x*b.y%mod+y*b.x%mod)%mod,res.z=z;return res;}
};

inline ll read(){
    ll x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0';
    return x*f;
}

inline ll pwi(ll a,ll b){ll ans=1;while(b)ans=(b&1)?ans*a%mod:ans,a=a*a%mod,b>>=1;return ans;}
inline vc mp(ll x,ll y,ll z){vc res;res.x=x,res.y=y,res.z=z;return res;}
inline vc pwv(vc a,ll b){vc ans=mp(1,0,a.z);while(b)ans=(b&1)?ans*a:ans,a=a*a,b>>=1;return ans;}
inline vc inv(vc a){ll iv=pwi((a.x*a.x%mod-a.z*a.y%mod*a.y%mod+mod)%mod,mod-2);return mp(a.x*iv%mod,(mod-a.y)*iv%mod,a.z);}

inline void init(ll n){
    S[0][0]=1;for(ll i=1;i<=n;i++)for(ll j=1;j<=i;j++)S[i][j]=(S[i-1][j-1]+(i-1)*S[i-1][j]%mod)%mod;
    C[0][0]=1;for(ll i=1;i<=n;i++){C[i][0]=1;for(ll j=1;j<=i;j++)C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;}
    fac[0]=1;for(ll i=1;i<=n;i++)fac[i]=fac[i-1]*i%mod;
    ifac[n]=pwi(fac[n],mod-2);for(ll i=n-1;i>=0;i--)ifac[i]=ifac[i+1]*(i+1)%mod;
}

int main(){
    init(501); ll T=read(),m=(read()&1)?3:5;
    while(T--){
        ll L=read(),R=read(),l=(m==5)?(L+1):(L+1)>>1,r=(m==5)?(R+1):(R>>1),k=read(),ans=0;
        vc A=(m==5)?mp(0,pwi(5,mod-2),m):mp(pwi(2,mod-2),pwi(6,mod-2),m),B=mp(A.x,mod-A.y,A.z);
        vc X=(m==5)?mp(pwi(2,mod-2),pwi(2,mod-2),m):mp(2,1,m),Y=mp(X.x,mod-X.y,X.z);
        for(ll i=0;i<=k;i++) for(ll j=0;j<=i;j++){
            ll val=S[k][i]%mod*(((k-i)&1)?(mod-1):1)%mod*C[i][j]%mod;
            vc S=pwv(A,j)*pwv(B,i-j),R=pwv(X,j)*pwv(Y,i-j),iv=inv(R-mp(1,0,m)),v=(pwv(R,r+1)-pwv(R,l))*iv;
            ans=(R.x==1&&R.y==0)?(ans+val*S.x%mod*((r-l+1)%mod)%mod)%mod:(ans+val*((S*v).x)%mod)%mod;
        }
        printf("%lld\n",ans*pwi((R-L+1)%mod,mod-2)%mod*ifac[k]%mod);
    }
    return 0;
}
勘破神机

 

posted @ 2020-06-16 08:09  Fugtemypt  阅读(139)  评论(0编辑  收藏  举报