洛谷P4351 [CERC2015]Frightful Formula

传送门

题解

写任意模数\(NTT\)的时候预处理系数写错了,精度爆炸了(痛哭)

首先\(c=0\)的时候答案很好计算,就是对于第一行第一列每个数算一下对\((n,n)\)的贡献即可

\(c\neq 0\)可以通过对于每一位上的\(c\)\((n,n)\)的贡献求和,发现这是一个卷积的形式,可以用任意模数\(NTT\)解决

但是有没有更好的办法消掉这个\(c\)

我们尝试把整个序列加上\(d\),使其满足

\[f_{i,j}+d=a(f_{i,j-1}+d)+b(f_{i-1,j}+d) \]

解得\(d={c\over a+b-1}\)

那么此时就转化成\(c=0\)的情况了,计算非常方便

//quming
#include<bits/stdc++.h>
#define R register
#define fp(i,a,b) for(R int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(R int i=(a),I=(b)-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
template<class T>inline bool cmin(T&a,const T&b){return a>b?a=b,1:0;}
template<class T>inline bool cmax(T&a,const T&b){return a<b?a=b,1:0;}
using namespace std;
typedef long long ll;
const int P=1e6+3;const double Pi=acos(-1.0);
inline void upd(R int &x,R int y){(x+=y)>=P?x-=P:0;}
inline int inc(R int x,R int y){return x+y>=P?x+y-P:x+y;}
int ksm(R int x,R int y){
	R int res=1;
	for(;y;y>>=1,x=1ll*x*x%P)if(y&1)res=1ll*res*x%P;
	return res;
}
const int N=(1<<19)+5;
int f[N],g[N],fac[N],ifac[N],ba[N],bb[N],k,n,a,b,c,res;
inline void init(int n){
	fac[0]=ifac[0]=1;fp(i,1,n)fac[i]=1ll*fac[i-1]*i%P;
	ifac[n]=ksm(fac[n],P-2);fd(i,n-1,1)ifac[i]=1ll*ifac[i+1]*(i+1)%P;
	ba[0]=bb[0]=1;fp(i,1,n)ba[i]=1ll*ba[i-1]*a%P,bb[i]=1ll*bb[i-1]*b%P;
}
inline int chs(R int n,R int m){return m>n?0:1ll*fac[n]*ifac[m]%P*ifac[n-m]%P;}
int main(){
//	freopen("formula.in","r",stdin);
//	freopen("formula.out","w",stdout);
	scanf("%d%d%d%d",&n,&a,&b,&c),k=1ll*c*ksm(a+b-1,P-2)%P;
	fp(i,1,n)scanf("%d",&f[i]),upd(f[i],k);
	fp(i,1,n)scanf("%d",&g[i]),upd(g[i],k);
	init(n<<1);
	fp(i,2,n)upd(res,1ll*g[i]*ba[n-i]%P*bb[n-1]%P*chs(n-2+n-i,n-i)%P);
	fp(i,2,n)upd(res,1ll*f[i]*ba[n-1]%P*bb[n-i]%P*chs(n-2+n-i,n-i)%P);
	printf("%d\n",inc(res,P-k));
	return 0;
}
posted @ 2020-06-18 15:49  源曲明  阅读(195)  评论(0编辑  收藏  举报