考虑第pp行的每个数对询问的贡献。
对于x>px>p,观察fi,j=afi−1,j+bfi−1,j−1,fi,j=afi−1,j+bfi−1,j−1,每个fp,ifp,i相当于向下走一步并×a×a,或者向右下走一步并×b×b,再给路径条数计下数,就有
fx,y=∑i=1yfp,iax−p−y+iby−i(x−py−i)fx,y=∑i=1yfp,iax−p−y+iby−i(x−py−i)
对于x<px<p,把式子变形成fi,j=1afi+1,j−bafi,j−1fi,j=1afi+1,j−bafi,j−1,相当于向上走一步并×1a×1a,或者向右走一步并×(−ba)×(−ba)(且不能再第pp行),就有
复杂度O(nq+m)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;
}