#4028. table

题目描述
C 酱有一个 m \times n m×n 的数表,行与列的编号都从 1 1 开始。令 f i,j

表示表格第 i i 行第 j j 列内的数,那么对于表格的第 i (i > 1) i(i>1) 行有

在这里插入图片描述

然而 C 酱已经把表格中的数忘得差不多了,他现在只记得第 p 行的数。他希望你能够帮忙还原出部分位置的数值。

输入格式
输入第一行为 66 个整数 m,n,a,b,p,q其中 q表示询问的个数。
接下来 qq 行,每行两个整数 x,yx,y,表示 C 酱询问你 fx,y的数值。

输出格式
输出共 qq 行,依次表示每个询问的答案在模 998244353 意义下的取值。

即设答案可以表示为分式 a/b ,则输出整数 x 使得 b \times x \equiv a \pmod {998244353}b×x≡a(mod998244353) 且 0 \leqslant x < 9982443530⩽x<998244353。可以证明这样的整数 x 是唯一的。

样例
样例输入 1
5 4 1 1 3 5
1 0 0 0
5 2
3 1
1 2
2 3
4 3
样例输出 1
2
1
998244351
1
0
样例输入 2
10 5 233 2333 6 4
9 3 1 0 10
1 5
10 2
5 3
8 1
样例输出 2
110343631
118211750
770559638
488601
数据范围与提示
对于 100%100% 的数据,保证 1 \leq q \leq 100 , 1 \leq x , p \leq m , 1 \leq y \leq n , 1 \leq a,b < 998244353,0 \leq f_{i,j} < 9982443531≤q≤100,1≤x,p≤m,1≤y≤n,1≤a,b<998244353,0≤f i,j <998244353。

来源
2018年3月雅礼集训
题解:
首先,对于在p行下方的点,我们可以计算p行的每个点对于该点的贡献。
由于公式
在这里插入图片描述
可知可以等价为每个点可以乘a向下走,或者乘b向右下走。
在计算时就可以采用组合计数。
再者,对于在p行上方的点,我们也可以同理,不过公式应该变形为
f[i][j]=1/a* f[i+1][j]-b/a*f[i][j-1];
此时等价于每个点可以向上除a,或向右乘b除a。

注意:
计算乘法逆元时可以倒着/正着递推,省时
向上计算时注意总步数因为p-x+y-i+1,向上走的步数是p-x-1。(emm我也不太清楚为什么)

感谢@jacky大佬修改查错。orz orz

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define N 100005+10000005
using namespace std;
const long long mod=998244353;

long long n,m,a,b,p,q;
long long a_sqrt[N],b_sqrt[N];
long long jcinva[N],jcinvb[N];
long long f[N];
long long cc[N],jcinvcc[N];
long long power(long long x,long long b){
	long long c=x,ans=1;
	while(b){
		if(b&1)ans=(ans*c)%mod;
		c=(c*c)%mod;b>>=1;
	}
	//return ans%mod;
	return ans;
}
int main()
{
	cin>>m>>n>>a>>b>>p>>q;
	for(int i=1;i<=n;i++){
		cin>>f[i];
	}
	cc[0]=1;jcinvcc[0]=1;
	a_sqrt[0]=jcinva[0]=1;
	b_sqrt[0]=jcinvb[0]=1;
	int inva=power(a,mod-2);
	for(int i=1;i<=n+m;i++){
		a_sqrt[i]=(a_sqrt[i-1]*a)%mod;
		jcinva[i]=(jcinva[i-1]*inva)%mod;
		b_sqrt[i]=(b_sqrt[i-1]*b)%mod;
		//jcinvb[i]=(jcinvb[i-1]*power(b,mod-2))%mod;
		jcinvb[i]=(jcinvb[i-1]*(mod-b*inva%mod))%mod;
		cc[i]=(cc[i-1]*i)%mod;
		//jcinvcc[i]=power(cc[i],mod-2);
		//cout<<b_sqrt[i]<<" "<<jcinvb[i]<<endl;
	}
	jcinvcc[n+m]=power(cc[n+m],mod-2);
	for(int i=n+m-1;i>=0;i--) jcinvcc[i]=(jcinvcc[i+1]*(i+1))%mod;
	for(int g=1;g<=q;g++){
		int x,y;cin>>x>>y;
		long long ans=0;
		if(x==p){cout<<f[y]<<endl;continue;}
		if(x>p){
			for(int i=1;i<=y;i++){
				if(x-p<y-i)continue;
				ans+=(f[i]%mod*cc[x-p]%mod*jcinvcc[y-i]%mod*jcinvcc[x-p-y+i]%mod*a_sqrt[x-p-y+i]
				%mod*b_sqrt[y-i]%mod);
				ans%=mod;
			}
			//cout<<(ans+mod)%mod<<endl;
			cout<<ans<<endl;
		}else{
			for(int i=1;i<=y;i++){
				//long long now=1;
				//now*=(f[i]%mod*cc[p-x+y-i-1]%mod)%mod;now=(now%mod+mod)%mod;
				//now*=(jcinvcc[p-x-1]%mod*jcinvcc[y-i]%mod)%mod;now=(now%mod+mod)%mod;
				//now*=(jcinva[p-x+y-i]%mod*b_sqrt[y-i]%mod)%mod;now=(now%mod+mod)%mod;
				//now*=power(-1,y-i);now=(now%mod+mod)%mod;
				//ans=ans+now;
				//ans=((ans+now)%mod+mod)%mod;
				//cout<<f[i]<<" "<<cc[p-x+y-i]<<" "<<jcinvcc[p-x]<<" "<<jcinvcc[y-i]<<" "<<jcinva[p-x]
				//<<" "<<b_sqrt[y-i]<<" "<<jcinva[y-i]<<" "<<power(-1,y-i)<<endl;
				ans=(ans+f[i]*cc[p-x+y-i-1]%mod*jcinvcc[p-x-1]%mod*jcinvcc[y-i]%mod*jcinva[p-x]%mod*jcinvb[y-i]%mod)%mod;
				ans=(ans+mod)%mod;
			}
			cout<<ans<<endl;
		}
	}
	//cout<<power(-1,1)<<endl;
	return 0;
}
/*
10 5 233 2333 6 4
9 3 1 0 10
1 5
10 2
5 3
8 1
*/
/*
5 4 1 1 3 5
1 0 0 0
5 2
3 1
1 2
2 3
4 3
*/
				
			
	
	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值