校内省选比赛D2

(⊙o⊙)…今天有点迷啊
T1

在这里插入图片描述

  • emm。首先p=1,可以直接 n ∗ m n*m nm递推,都会吧。有20分。
  • 再来考虑 p ! = 1 p!=1 p!=1的情况。因为 f [ i ] [ j ] = f [ i − 1 ] [ j − 1 ] ∗ b + f [ i − 1 ] [ j ] ∗ a f[i][j]=f[i-1][j-1]*b+f[i-1][j]*a f[i][j]=f[i1][j1]b+f[i1][j]a,所以我们可以一列一列把所有答案求出来,即 n ∗ m n*m nm预处理, O ( 1 ) O(1) O(1)求。40分get。
  • 还是p=1的情况,此时 n , m &lt; = 500000 n,m&lt;=500000 n,m<=500000。因此我们需要转换思路。画一个图,给某一行的每一列分别设定一个变量。递推表示一下,你发现,每一个 f [ 1 ] [ i ] f[1][i] f[1][i] f [ x ] [ y ] f[x][y] f[x][y]的贡献,即是 f [ 1 ] [ i ] f[1][i] f[1][i]本身乘上一个组合数,再乘上一个a的幂次和b的幂次。至于组合数具体是多少呢?很容易推出来,组合数是到达当前点的方案数吧,从上向下走,显然只有斜着走和正下方走,那么组合数为 C x − 1 y − i C_{x-1}^{y-i} Cx1yi。b的幂次即为斜着走的步数,显然为 y − i y-i yi,那么a就是 x − 1 − y + i x-1-y+i x1y+i啦。okk,60分get。
  • 100分的做法需要我们推一下,当x在p上面时,怎么算。考虑,假设我们要求 f ( x , y ) f(x,y) f(x,y),它等于 f ( x + 1 , y ) − f ( x , y − 1 ) ∗ b a \frac{f(x+1,y)-f(x,y-1)*b}{a} af(x+1,y)f(x,y1)b。这其实又变成了一个可以递推的式子,不断分解 f ( x + 1 , y ) 和 f ( x , y − 1 ) f(x+1,y)和f(x,y-1) f(x+1,y)f(x,y1)。直到 x = p x=p x=p停止。这仍然是一个组合数,只不过有正负区别。写一写,显然当列之间距离为奇数时,系数为负。否则为正。因为这次走法不同,只能向左或者向下,所以组合数是 C p − x + y − i − 1 p − x − 1 C_{p-x+y-i-1}^{p-x-1} Cpx+yi1px1,减1是因为最后一行不能向左走。从式子中可以看出,b仍然是需要乘的,但是a需要除。b的幂还是 y − i y-i yi,a的幂变成 p − x + y − i p-x+y-i px+yi。okk。
    p &gt; x , f [ x ] [ y ] = ∑ i = 1 y f [ p ] [ i ] ∗ C p − x + y − i − 1 p − x − 1 ∗ b y − i a p − x + y − i p&gt;x,f[x][y]=\sum_{i=1}^{y}\frac{f[p][i]*C_{p-x+y-i-1}^{p-x-1}*b^{y-i}}{a^{p-x+y-i}} p>x,f[x][y]=i=1yapx+yif[p][i]Cpx+yi1px1byi
    p &lt; x , f [ x ] [ y ] = ∑ i = 1 y f [ p ] [ i ] ∗ C x − p y − i ∗ a x − p − y + i ∗ b y − i p&lt;x,f[x][y]=\sum_{i=1}^{y}f[p][i]*C_{x-p}{y-i}*a^{x-p-y+i}*b^{y-i} p<x,f[x][y]=i=1yf[p][i]Cxpyiaxpy+ibyi
Coding
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll N=15e6+100;
const ll mod=998244353;
ll n,m,a,b,p,q,jie[N],njie[N],inv[N],f[N],posa[N],posb[N];
ll read(){
	char ch=getchar();ll num=0,f=1;
	while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
	while(isdigit(ch)){num=(num<<1)+(num<<3)+(ch^48);ch=getchar();}
	return num*f;
}
void work(){
	inv[1]=1;
	for(ll i=2;i<=n+m;++i){
		ll x=-(ll)(mod/i)*inv[mod%i]%mod;
		inv[i]=(x+mod)%mod;
	}
	jie[0]=njie[0]=1;
	for(ll i=1;i<=n+m;++i) jie[i]=(ll)jie[i-1]*i%mod,njie[i]=(ll)njie[i-1]*inv[i]%mod;
	posa[0]=posb[0]=1;
	for(ll i=1;i<=n+m;++i) posa[i]=(ll)posa[i-1]*a%mod,posb[i]=(ll)posb[i-1]*b%mod;
}
ll power(ll a,ll b){
	ll res=1%mod;
	for(;b;b>>=1){ 
		if(b&1) res=(ll)res*a%mod;
		a=(ll)a*a%mod;
	}
	return res;
}
int main(){
	freopen("table.in","r",stdin);
	freopen("table.out","w",stdout);
	n=read(),m=read(),a=read(),b=read(),p=read(),q=read();
	for(ll i=1;i<=m;++i) f[i]=read();
	work();
	while(q--){
		ll x=read(),y=read();
		if(x==p) printf("%d\n",f[y]);
		else if(x>p){
			ll res=0;
			for(ll i=1;i<=y;++i){
				ll c;
				if(x-p<y-i) c=0;
				else c=jie[x-p]*njie[y-i]%mod*njie[x-p-y+i]%mod;
				res+=(ll)f[i]*posa[x-p-y+i]%mod*posb[y-i]%mod*c%mod;
				res=(res+mod)%mod;
			}
			printf("%lld\n",res);
		}else if(x<p){
			ll res=0;
			for(ll i=1;i<=y;++i){
				ll c;
				if(p-x+y-i<p-x) c=0;
				else c=jie[p-x+y-i-1]*njie[p-x-1]%mod*njie[y-i]%mod;
				if((y-i)%2==1) res-=(ll)f[i]*posb[y-i]%mod*c%mod*power(posa[y-i+p-x],mod-2)%mod;
				else res+=(ll)f[i]*posb[y-i]%mod*c%mod*power(posa[y-i+p-x],mod-2)%mod;
				res=(res+mod)%mod;
			}
			printf("%lld\n",res);
		}
	}
	return 0;
}
T2与T3,神仙题,咕咕咕
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值