[2018雅礼省选集训3-30]table 递推

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/DOFYPXY/article/details/79962603

考虑第p行的每个数对询问fx,y的贡献。
对于x>p,观察fi,j=afi1,j+bfi1,j1每个fp,i相当于向下走一步并×a,或者向右下走一步并×b,再给路径条数计下数,就有

fx,y=i=1yfp,iaxpy+ibyi(xpyi)

对于x<p,把式子变形成fi,j=1afi+1,jbafi,j1,相当于向上走一步并×1a,或者向右走一步并×(ba)(且不能再第p行),就有
fx,y=i=1yfp,i(b)yiapx+yi(yi+px1px1)

复杂度O(nq+m)
代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define N 100010
#define M 10100010
#define up(x,y) (x=(x+(y))%mod) 
using namespace std;
const int mod=998244353;
int m,n,a,b,p,q;
ll f[N],fac[M],ifac[M],pow_a[M],pow_b[M],ip_a[M];
int read()
{
    int x=0,f=1;char ch=getchar();
    for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=-1;
    for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
    return x*f; 
}
ll ksm(ll a,int b){ll r=1;for(;b;b>>=1){if(b&1)r=r*a%mod;a=a*a%mod;}return r;}
ll C(int a,int b){return a<b?0:fac[a]*ifac[b]%mod*ifac[a-b]%mod;}
int main()
{
    m=read();n=read();a=read();b=read();p=read();q=read();
    for(int i=1;i<=n;i++)
        f[i]=read();
    fac[0]=1;
    for(int i=1;i<=m+n;i++)
        fac[i]=fac[i-1]*i%mod;
    ifac[m+n]=ksm(fac[m+n],mod-2);
    for(int i=m+n-1;i>=0;i--)
        ifac[i]=ifac[i+1]*(i+1)%mod;
    pow_a[0]=pow_b[0]=1;
    for(int i=1;i<=m+n;i++)
        pow_a[i]=pow_a[i-1]*a%mod,pow_b[i]=pow_b[i-1]*b%mod;
    ip_a[1]=ksm(a,mod-2);
    for(int i=2;i<=m+n;i++)
        ip_a[i]=ip_a[i-1]*ip_a[1]%mod;
    while(q--)
    {
        int x=read(),y=read();ll ans=0;
        if(x>=p)
        {
            for(int k=max(0,y-x+p);k<=y;k++)
                up(ans,C(x-p,y-k)*pow_b[y-k]%mod*pow_a[x-p-y+k]%mod*f[k]);
        }
        else 
        {
            for(int k=y,v=1;k;k--,v=-v)
                up(ans,C(p-x+y-k-1,y-k)*pow_b[y-k]%mod*ip_a[p-x+y-k]%mod*f[k]%mod*v+mod);
        }
        printf("%lld\n",ans);
    }
    return 0;
}
阅读更多
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页