[ABC309Ex] Simple Path Counting Problem
Problem Statement
We have a grid with $N$ rows and $M$ columns. We denote by $(i,j)$ the cell in the $i$-th row from the top and $j$-th column from the left.
You are given integer sequences $A=(A_1,A_2,\dots,A_K)$ and $B=(B_1,B_2,\dots,B_L)$ of lengths $K$ and $L$, respectively.
Find the sum, modulo $998244353$, of the answers to the following question over all integer pairs $(i,j)$ such that $1 \le i \le K$ and $1 \le j \le L$.
- A piece is initially placed at $(1,A_i)$. How many paths are there to take it to $(N,B_j)$ by repeating the following move $(N-1)$ times?
- Let $(p,q)$ be the piece's current cell. Move it to $(p+1,q-1),(p+1,q)$, or $(p+1,q+1)$, without moving it outside the grid.
Constraints
- $1 \le N \le 10^9$
- $1 \le M,K,L \le 10^5$
- $1 \le A_i,B_j \le M$
先考虑如何计算某一个点到另一个点的方案数。
定义 \(dp_{i,j}\) 为到达 \((i,j)\) 的方案数,那么 \(dp_{i,j}=dp_{i-1,j-1}+dp_{i-1,j}+dp_{i-1,j+1}\)。
看似可以多项式快速幂优化,但是会发现有边界问题。
如何解决边界问题?对称一下,使 \(dp_{n+1-i}=-dp_i\),然后卷积的时候就可以把 \(j\le N\) 的限制给去掉。
\(x>0\) 的限制怎么去? 用 \(2n+2\) 的循环卷积即可。
然后循环卷积快速幂就可以了。
原题也一样,循环卷积跑出来 \((1+x+x^{-1})^N\) 的系数卷上 \(A\) 数组就可以了。
#include<bits/stdc++.h>
using namespace std;
const int N=524288,P=998244353;
int n,m,k,a,b,rr[N],ans,f[N],g[N],h[N],p,l;
int read()
{
int s=0;
char ch=getchar();
while(ch<'0'||ch>'9')
ch=getchar();
while(ch>='0'&&ch<='9')
s=s*10+ch-48,ch=getchar();
return s;
}
int pown(int x,int y)
{
if(!y)
return 1;
int t=pown(x,y>>1);
if(y&1)
return 1LL*t*t%P*x%P;
return 1LL*t*t%P;
}
void ntt(int a[],int op)
{
for(int i=1;i<N;i++)
if(rr[i]<i)
swap(a[i],a[rr[i]]);
for(int md=1;md<N;md<<=1)
{
int g=pown(op? 3:332748118,(P-1)/(md<<1));
for(int i=0;i<N;i+=md<<1)
{
int pw=1;
for(int j=0;j<md;j++,pw=1LL*g*pw%P)
{
int x=a[i+j+md]*1LL*pw%P;
a[i+j+md]=(a[i+j]+P-x)%P;
(a[i+j]+=x)%=P;
}
}
}
if(!op)
{
int ivN=pown(N,P-2);
for(int i=0;i<N;i++)
a[i]=1LL*a[i]*ivN%P;
}
}
void mul(int a[],int b[])
{
ntt(a,1);
ntt(b,1);
for(int i=0;i<N;i++)
a[i]=1LL*a[i]*b[i]%P;
ntt(a,0);
for(int i=p;i<N;i++)
(a[i%p]+=a[i])%=P,a[i]=0;
}
void solve(int x)
{
if(x==1)
return;
if(x&1)
{
solve(x-1);
memcpy(h,f,sizeof(h));
for(int i=0;i<p;i++)
f[i]=(1LL*h[i]+h[(i+p-1)%p]+h[(i+1)%p])%P;
}
else
{
solve(x>>1);
memcpy(h,f,sizeof(h));
mul(f,h);
}
}
int main()
{
n=read(),m=read(),k=read(),l=read();
p=2*m+2;
for(int i=0;i<N;i++)
rr[i]=rr[i>>1]>>1|(i&1)*(N/2);
for(int i=1;i<=k;i++)
a=read(),g[a]++,(g[2*m-a+2]+=P-1)%=P;
if(n^1)
{
f[0]=f[p-1]=f[1]=1;
solve(n-1);
mul(g,f);
}
for(int i=1;i<=l;i++)
(ans+=g[read()])%=P;
printf("%d",ans);
}
[ABC309Ex] Simple Path Counting Problem的更多相关文章
- BNU 4356 ——A Simple But Difficult Problem——————【快速幂、模运算】
A Simple But Difficult Problem Time Limit: 5000ms Memory Limit: 65536KB 64-bit integer IO format: %l ...
- CF 954H Path Counting
H. Path Counting time limit per test 5 seconds memory limit per test 256 megabytes input standard in ...
- hdu4975 A simple Gaussian elimination problem.(正确解法 最大流+删边判环)(Updated 2014-10-16)
这题标程是错的,网上很多题解也是错的. http://acm.hdu.edu.cn/showproblem.php?pid=4975 2014 Multi-University Training Co ...
- HDU-4972 A simple dynamic programming problem
http://acm.hdu.edu.cn/showproblem.php?pid=4972 ++和+1还是有区别的,不可大意. A simple dynamic programming proble ...
- hdu 4972 A simple dynamic programming problem(高效)
pid=4972" target="_blank" style="">题目链接:hdu 4972 A simple dynamic progra ...
- A simple Gaussian elimination problem.(hdu4975)网络流+最大流
A simple Gaussian elimination problem. Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65 ...
- Codeforces 954H Path Counting 【DP计数】*
Codeforces 954H Path Counting LINK 题目大意:给你一棵n层的树,第i层的每个节点有a[i]个儿子节点,然后问你树上的简单路径中长度在1~n*2-2之间的每个有多少条 ...
- UVA 1640 The Counting Problem UVA1640 求[a,b]或者[b,a]区间内0~9在里面各个数的数位上出现的总次数。
/** 题目:UVA 1640 The Counting Problem UVA1640 链接:https://vjudge.net/problem/UVA-1640 题意:求[a,b]或者[b,a] ...
- Codeforces 954H Path Counting(DP)
题目链接 Path Counting 题意 给定一棵高度为$n$的树,给出每一层的每个点的儿子个数(某一层的所有点儿子个数相同). 令$f_{k}$为长度为$k$的路径条数,求$f_{1}, ...
- HDOJ 4975 A simple Gaussian elimination problem.
和HDOJ4888是一样的问题,最大流推断多解 1.把ISAP卡的根本出不来结果,仅仅能把全为0或者全为满流的给特判掉...... 2.在残量网络中找大于2的圈要用一种类似tarjian的方法从汇点開 ...
随机推荐
- MindSponge分子动力学模拟——安装与使用(2023.08)
技术背景 昇思MindSpore是由华为主导的一个,面向全场景构建最佳昇腾匹配.支持多处理器架构的开放AI框架.MindSpore不仅仅是软件层面的工具,更重要的是可以协同华为自研的昇腾Ascend平 ...
- centos7.X安装nginx – 东凭渭水流
1.安装nginx需要使用root用户 2.配置nginx源 rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release ...
- WPF-封装自定义雷达图控件
源码地址:https://gitee.com/LiuShuiRuoBing/code_blog 雷达图用于表示不同内容的占比关系,在项目中有广泛的应用,但是目前未曾有封装良好的雷达图控件,鉴于最近项目 ...
- 探索ChatGPT的Fine-tuning和Embeddings
1.概述 今天我们将深入探索ChatGPT的两项核心技术:Fine-tuning(微调)和Embeddings(嵌入).这些技术在现代自然语言处理领域扮演着至关重要的角色,为模型的性能提升和适应特定任 ...
- MindSponge分子动力学模拟——定义一个分子系统(2023.08)
技术背景 在前面两篇文章中,我们分别介绍了分子动力学模拟软件MindSponge的软件架构和安装与使用教程.这里我们进入到实用化阶段,假定大家都已经在本地部署好了基于MindSpore的MindSpo ...
- 基于velero及minio实现etcd数据备份与恢复
1.Velero简介 Velero 是vmware开源的一个云原生的灾难恢复和迁移工具,它本身也是开源的,采用Go语言编写,可以安全的备份.恢复和迁移Kubernetes集群资源数据:官网https: ...
- 浅析依赖属性(DependencyProperty)
在WPF中,引入了依赖属性这个概念,提到依赖属性时通常都会说依赖属性能节省实例对内存的开销.此外依赖属性还有两大优势. 支持多属性值,依赖属性系统可以储存多个值,配合Expression.Style. ...
- 记一次基于 PowerShell 的 Git 自动化部署 Java 多服务实践
前言 有这么一个自动化部署的需求,凑巧 git 还直接建立在测试服务器上,部署后可以直接在测试服务器上演示 步骤 建立 Git 仓库 与一般的 Git 部署一样,区别是需要添加 --bare 开关,这 ...
- Fortran 的简单入门和使用 OpenMPI
Fortran 与 C-like 语言的区别简单总结 无大括号,使用关键字画出范围: C++: int main() { } Fortran: program test implicit none e ...
- 文心一言 VS 讯飞星火 VS chatgpt (112)-- 算法导论10.2 3题
三.用go语言,用一个单链表L实现一个队列.要求操作 ENQUEUE 和 DEQUEUE 的运行时间仍为O(1). 文心一言: 在 Go 语言中,使用单链表实现队列的操作,包括入队(ENQUEUE)和 ...