正题

题目链接:https://www.luogu.com.cn/problem/P4351


题目大意

\(n*n\)的矩形,给出第一行和第一列的数,剩下的满足\(F_{i,j}=a*F_{i,j-1}+b*F_{i-1,j}+c\)

求\(F_{n,n}\)


解题思路

第一眼看以为是水题,因为给出的数字的贡献通过组合数很好算,但是后来发现麻烦的是那个\(c\)。我们考虑每个格子的\(c\)产生的贡献。

下面为了方便我们先默认让所有格子横纵坐标减\(1\)

对于一个格子\((i,j)\),通过它的路径有\(\binom{2n-i-j}{n-i}\)种,然后产生的贡献是\(a^{n-i}b^{n-j}\)。为了方便我们反过来表示,然后因为第一行第一列没有贡献所以\(n\)减一。

那么总共的贡献就是

\[\sum_{i=0}^n\sum_{j=0}^na^ib^i\binom{i+j}{i}
\]

然后因为有\(i+j\)很麻烦,考虑枚举\(i+j\)就有

\[\sum_{i=0}^{2n}\sum_{j=max\{0,i-n\}}^{min\{i,n\}}a^jb^{i-j}\frac{(i+j)!}{j!(i-j)!}
\]

把\((i+j)!\)拿出去就是一个卷积的形式了,模数比较丑所以要用\(MTT\)来做。(除了\(MTT\)部分全部自己推?)。

记得要预处理单位根,不然会被卡精度,时间复杂度\(O(n\log n)\)(常数巨大)

好像有更简单的做法就是用一个\(x\)满足\(ax+bx+c=x\)的来消掉\(c\)这个元就可以直接做了,但是我不会。


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
const double Pi=acos(-1);
const ll N=2e6+10,P=1e6+3;
ll n,a,b,c,ans,F[N],H[N],G[N];
ll inv[N],fac[N],r[N],apw[N],bpw[N];
ll power(ll x,ll b){
ll ans=1;
while(b){
if(b&1)ans=ans*x%P;
x=x*x%P;b>>=1;
}
return ans;
}
ll C(ll n,ll m)
{return fac[n]*inv[m]%P*inv[n-m]%P;}
namespace Poly{
const ll seq=32768;
struct complex{
double x,y;
complex(double xx=0,double yy=0)
{x=xx;y=yy;}
}A[N],B[N],C[N],D[N],w[N];
complex operator+(complex a,complex b)
{return complex(a.x+b.x,a.y+b.y);}
complex operator-(complex a,complex b)
{return complex(a.x-b.x,a.y-b.y);}
complex operator*(complex a,complex b)
{return complex(a.x*b.x-a.y*b.y,a.x*b.y+a.y*b.x);}
void FFT(complex *f,ll n,ll op){
for(ll i=0;i<n;i++)
if(i<r[i])swap(f[i],f[r[i]]);
for(ll p=2;p<=n;p<<=1){
ll len=p>>1;
for(ll k=0;k<n;k+=p){
for(ll i=k;i<k+len;i++){
complex tmp=w[n/len*(i-k)];
if(op==-1)tmp.y=-tmp.y;
complex tt=f[i+len]*tmp;
f[i+len]=f[i]-tt;
f[i]=f[i]+tt;
}
}
}
if(op==-1){
for(ll i=0;i<n;i++)
f[i].x=fabs(f[i].x/n+0.5);
}
return;
}
void MTT(ll *a,ll *b,ll *c,ll n,ll m){
ll l=1;
while(l<=n+m)l<<=1;
for(ll i=0;i<l;i++)
r[i]=(r[i>>1]>>1)|((i&1)?(l>>1):0);
for (ll k=1;k<l;k<<=1)
for (ll i=0;i<k;i++)
w[l/k*i]=(complex){cos(i*Pi/k),sin(i*Pi/k)};
for(ll i=0;i<n;i++)A[i].x=a[i]/seq,B[i].x=a[i]%seq;
for(ll i=0;i<m;i++)C[i].x=b[i]/seq,D[i].x=b[i]%seq;
FFT(A,l,1);FFT(B,l,1);FFT(C,l,1);FFT(D,l,1);
complex t1,t2;
for(ll i=0;i<l;i++){
t1=A[i]*C[i];t2=B[i]*D[i];
B[i]=A[i]*D[i]+B[i]*C[i];
A[i]=t1;C[i]=t2;
}
FFT(A,l,-1);FFT(B,l,-1);FFT(C,l,-1);
for(ll i=0;i<l;i++){
c[i]=(c[i]+(ll)(A[i].x)*seq%P*seq%P)%P;
c[i]=(c[i]+(ll)(B[i].x)*seq%P)%P;
c[i]=(c[i]+(ll)(C[i].x))%P;
}
return;
}
}
void init(){
inv[1]=1;apw[0]=bpw[0]=1;
for(ll i=1;i<=2*n;i++)
apw[i]=apw[i-1]*a%P,bpw[i]=bpw[i-1]*b%P;
for(ll i=2;i<=2*n;i++)
inv[i]=(P-(P/i)*inv[P%i]%P)%P;
inv[0]=fac[0]=1;
for(ll i=1;i<=2*n;i++){
fac[i]=fac[i-1]*i%P;
inv[i]=inv[i-1]*inv[i]%P;
}
}
signed main()
{
scanf("%lld%lld%lld%lld",&n,&a,&b,&c);
init();n--;
for(ll i=0;i<=n;i++){
ll x;scanf("%lld",&x);
if(!i)continue;
x=x*bpw[n-i]%P*apw[n]%P;
(ans+=x*C(n+n-i-1,n-1)%P)%=P;
}
for(ll i=0;i<=n;i++){
ll x;scanf("%lld",&x);
if(!i)continue;
x=x*apw[n-i]%P*bpw[n]%P;
(ans+=x*C(n+n-i-1,n-1)%P)%=P;
}//处理已知数列 for(ll i=0;i<n;i++){
F[i]=apw[i]*inv[i]%P;
H[i]=bpw[i]*inv[i]%P;
}
Poly::MTT(F,H,G,n,n);
for(ll i=0;i<2*n-1;i++)
(ans+=G[i]*c%P*fac[i]%P)%=P;
// for(ll i=0;i<=n;i++){
// (ans+=P-apw[n-i]*bpw[n]%P*c%P*C(n+n-i,n)%P)%=P;
// if(!i)continue;
// (ans+=P-bpw[n-i]*apw[n]%P*c%P*C(n+n-i,n)%P)%=P;
// }
printf("%lld\n",ans);
return 0;
}

P4351-[CERC2015]Frightful Formula【组合数学,MTT】的更多相关文章

  1. bzoj 4451 : [Cerc2015]Frightful Formula FFT

    4451: [Cerc2015]Frightful Formula Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 177  Solved: 57[Sub ...

  2. LG4351 [CERC2015]Frightful Formula

    Frightful Formula 给你一个\(n\times n\)矩阵的第一行和第一列,其余的数通过如下公式推出: \[f_{i,j}=a\cdot f_{i,j-1}+b\cdot f_{i-1 ...

  3. BZOJ4451 [Cerc2015]Frightful Formula 多项式 FFT 递推 组合数学

    原文链接http://www.cnblogs.com/zhouzhendong/p/8820963.html 题目传送门 - BZOJ4451 题意 给你一个$n\times n$矩阵的第一行和第一列 ...

  4. BZOJ4451 : [Cerc2015]Frightful Formula

    $(i,1)$对答案的贡献为$l_iC(2n-i-2,n-i)a^{n-1}b^{n-i}$. $(1,i)$对答案的贡献为$t_iC(2n-i-2,n-i)*a^{n-i}b^{n-1}$. $(i ...

  5. Frightful Formula Gym - 101480F (待定系数法)

    Problem F: Frightful Formula \[ Time Limit: 10 s \quad Memory Limit: 512 MiB \] 题意 题意就是存在一个\(n*n\)的矩 ...

  6. Gym 101480F Frightful Formula(待定系数)题解

    #include<cmath> #include<set> #include<map> #include<queue> #include<cstd ...

  7. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  8. 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/常用套路【入门】

    原文链接https://www.cnblogs.com/zhouzhendong/p/Fast-Fourier-Transform.html 多项式 之 快速傅里叶变换(FFT)/数论变换(NTT)/ ...

  9. FFT与NTT专题

    先不管旋转操作,考虑化简这个差异值 $$begin{aligned}sum_{i=1}^n(x_i-y_i-c)^2&=sum_{i=1}^n(x_i-y_i)^2+nc^2-2csum_{i ...

随机推荐

  1. tcp为什么要三次握手,tcp为什么可靠

    转自 : https://www.cnblogs.com/LUO77/p/5771237.html大体看过,没有深入研究,有需要时继续看. 为什么不能两次握手:(防止已失效的连接请求又传送到服务器端, ...

  2. C# 不是异步的方法中获取异步的结果

    var waiter = HP.UtilsLib.TaskAwaiterHelper.GetTaskAwaiter( async () => { return await feedBack(ve ...

  3. Redis(三):新数据类型

    配置文件redis.conf详解 bind=127.0.0.1 # 表示只能在本机中访问redis,将该行注释掉,即可接收任何IP地址的访问 protected-mode # 设置为no,表示关闭保护 ...

  4. Golang gomail 发送邮件 --初使用

    gomail是一个第三方库,可以发送邮件 安装:go get -u github.com/go-gomail/gomail 使用示例: m := gomail.NewMessage() m.SetHe ...

  5. configparser生成模块写

    # -*-coding:utf-8-*-__author__ = "logan.xu"#写配置文件import configparserconfig = configparser. ...

  6. cmd(命令行 )的命令

    cmd是command的缩写.即命令行 CMD命令锦集 1. gpedit.msc-----组策略 2. sndrec32-------录音机 3. Nslookup-------IP地址侦测器 ,是 ...

  7. Selenium4 IDE初体验

    今天闲来无事,尝试了一番Selenium4的IDE,提供了录制和回放的功能.下面是对它的简单介绍. 安装 下载地址:https://www.selenium.dev/selenium-ide/ 在下载 ...

  8. ☕【Java技术指南】「难点-核心-遗漏」Java线程状态流转及生命周期的技术指南(知识点串烧)!

    前提介绍 本章主要介绍相关线程声明周期的转换机制以及声明周期的流转关系以及相关AQS的实现和相关的基本原理,配合这相关官方文档的中英文互译的介绍. 线程状态流转及生命周期 当线程被创建并启动以后,它既 ...

  9. idea配置tomcat及中文乱码解决

    放在前面:不要使用tomcat10,访问自己的页面会报404错误,目前无解,在这个坑爬了一下午,最终换了tomcat 9才解决.所以我选择了tomcat 9 + idea 2021.2版本 配置步骤: ...

  10. python爬区csdn文章信息(原始稿)

    使用python对csdn的博主文章进行爬取,期间又遇到了新的问题和旧的已经遇到过的问题.首先做一个笔记,免得以后遇到同样的问题时还得浪费时间和经历. 刚开始目的没那么明确,主要在于熟悉相关的规则及流 ...