出题人你具体数学看多了吧
arrow_king · · 题解
读完题:这不就是个多米诺骨牌。。。
我们先求出
对于
对于
考虑建立递归关系,容易得到
联立解生成函数我们可以得到
解出
我们观察到上面的式子都有形式
欲求的答案为
化简求和式可以得到
此时对
观察到通项公式内带有大量
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std;
#define ll long long
#define il inline
#define mod 998244353
#define N 550
il ll read() {
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {if(c=='-') {f=-1;} c=getchar();}
while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
ll i_square;
struct complex {
ll re,im;
complex() {re=im=0;}
complex(ll _re,ll _im) {re=_re,im=_im;}
};
il complex operator +(complex a,complex b) {return complex((a.re+b.re)%mod,(a.im+b.im)%mod);}
il complex operator -(complex a) {return complex((mod-a.re)%mod,(mod-a.im)%mod);}
il complex operator -(complex a,complex b) {return a+(-b);}
il complex operator *(complex a,complex b) {return complex((a.re*b.re%mod+i_square*a.im*b.im%mod)%mod,(a.im*b.re%mod+a.re*b.im%mod)%mod);}
il complex operator *(complex a,ll b) {return complex(a.re*b%mod,a.im*b%mod);}
il complex operator *(ll b,complex a) {return complex(a.re*b%mod,a.im*b%mod);}
il complex Conj(complex a) {a.im=(mod-a.im)%mod;return a;}
il ll qpow(ll a,ll b) {ll ans=1;for(;b;b>>=1,a=a*a%mod)if(b&1)ans=ans*a%mod;return ans;}
il complex qpow(complex a,ll b) {
complex ans(1,0);
for(;b;b>>=1,a=a*a)if(b&1)ans=ans*a;return ans;
}
ll C[N][N],S[N][N],fac[N],t,m;
complex A,B,alpha,beta;
il void pre_init(int m) {
if(m==2) {
i_square=5;
A=complex(qpow(2,mod-2),qpow(10,mod-2)),B=Conj(A);
alpha=complex(qpow(2,mod-2),qpow(2,mod-2)),beta=Conj(alpha);
}
else {
i_square=3;
A=complex(qpow(2,mod-2),qpow(6,mod-2)),B=Conj(A);
alpha=complex(2,1),beta=Conj(alpha);
}
}
il void init_CS(int n) {
C[0][0]=1;for(int i=1;i<=n;i++) C[i][0]=1;
S[0][0]=1;
for(int i=1;i<=n;i++) {
for(int j=1;j<=i;j++) {
C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;
S[i][j]=((i-1)*S[i-1][j]+S[i-1][j-1])%mod;
}
}
fac[0]=1;for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%mod;
}
il complex Inv(complex a) {
return Conj(a)*qpow((a.re*a.re%mod-i_square*a.im*a.im%mod+mod)%mod,mod-2);
}
il complex Add(complex bas,ll n) {
if(bas.re==1&&bas.im==0) {return complex(n%mod,0);}
complex tmp=qpow(bas,n+1)-complex(1,0);
return tmp*Inv(bas-complex(1,0));
}
il void mian() {
ll l=read(),r=read(),k=read();
complex ans(0,0);
for(int j=0;j<=k;j++) {
for(int p=0;p<=j;p++) {
complex now=C[j][p]*qpow(A,p)*qpow(B,j-p),bas=qpow(alpha,p)*qpow(beta,j-p);
complex sum;
if(m==2) sum=Add(bas,r)-Add(bas,(l-1));
else sum=Add(bas,r/2)-Add(bas,(l-1)/2);
if((k-j)%2==0) ans=ans+S[k][j]*now*sum;
else ans=ans-S[k][j]*now*sum;
}
}
ans=ans*qpow(fac[k],mod-2);
printf("%lld\n",ans.re*qpow((r-l+1)%mod,mod-2)%mod);
}
int main() {
t=read(),m=read();
pre_init(m);
init_CS(510);
while(t--) mian();
return 0;
}
UPD on 2024.10.28:公式里