校内省选比赛D2

博客主要围绕T1题展开,介绍了不同情况下的解题思路。当p=1时,可通过n*m递推得20分,还可转换思路利用组合数等得60分;p!=1时,通过n*m预处理和O(1)求解得40分;100分做法需进一步推导递推式子,根据x与p的大小关系得出不同公式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

在这里插入图片描述

  • emm。首先p=1,可以直接n∗mn*mnm递推,都会吧。有20分。
  • 再来考虑p!=1p!=1p!=1的情况。因为f[i][j]=f[i−1][j−1]∗b+f[i−1][j]∗af[i][j]=f[i-1][j-1]*b+f[i-1][j]*af[i][j]=f[i1][j1]b+f[i1][j]a,所以我们可以一列一列把所有答案求出来,即n∗mn*mnm预处理,O(1)O(1)O(1)求。40分get。
  • 还是p=1的情况,此时n,m&lt;=500000n,m&lt;=500000n,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的幂次。至于组合数具体是多少呢?很容易推出来,组合数是到达当前点的方案数吧,从上向下走,显然只有斜着走和正下方走,那么组合数为Cx−1y−iC_{x-1}^{y-i}Cx1yi。b的幂次即为斜着走的步数,显然为y−iy-iyi,那么a就是x−1−y+ix-1-y+ix1y+i啦。okk,60分get。
  • 100分的做法需要我们推一下,当x在p上面时,怎么算。考虑,假设我们要求f(x,y)f(x,y)f(x,y),它等于f(x+1,y)−f(x,y−1)∗ba\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=px=px=p停止。这仍然是一个组合数,只不过有正负区别。写一写,显然当列之间距离为奇数时,系数为负。否则为正。因为这次走法不同,只能向左或者向下,所以组合数是Cp−x+y−i−1p−x−1C_{p-x+y-i-1}^{p-x-1}Cpx+yi1px1,减1是因为最后一行不能向左走。从式子中可以看出,b仍然是需要乘的,但是a需要除。b的幂还是y−iy-iyi,a的幂变成p−x+y−ip-x+y-ipx+yi。okk。
    p&gt;x,f[x][y]=∑i=1yf[p][i]∗Cp−x+y−i−1p−x−1∗by−iap−x+y−ip&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=1yf[p][i]∗Cx−py−i∗ax−p−y+i∗by−ip&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,神仙题,咕咕咕
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值