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

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

fx,y=i=1yfp,iaxpy+ibyi(xpyi) f x , y = ∑ i = 1 y f p , i a x − p − y + i b y − i ( x − p y − i )

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

复杂度 O(nq+m) O ( n q + 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值