ABC240 G - Teleporting Takahashi

ABC240 G - Teleporting Takahashi 题解

题目简介

给出 n(1n107)x,y,z(107x,y,z107) ,求长度为 n+1 的三元组序列 (xi,yi,zi)(0in) 满足:

  • (x0,y0,z0)=(0,0,0)
  • (xn,yn,zn)=(x,y,z)
  • |xixi1|+|yiyi1|+|zizi1|=1

输出方案数对 998244353 取模的结果。

URL = https://atcoder.jp/contests/abc240/tasks/abc240_g

Hint 1 : 2D

如果我们考虑下列一个简化问题,从 (0,0) 走到 (x,y) ,总共走了k 步,方案数为多少。

事实上,这个简化版本可以用 O(1) 的时间复杂度计算。

x 轴走一步,相当于加上一个向量(±1,0), y 轴走一步,相当于加上一个向量(0,±1)

如果考虑将坐标系从 (x,y) 映射到 (x+y,xy),那么上述四个步骤可以表示为加上向量:(±1,±1)

因此,将两个维度分别考虑即可,即对于 1D 维度,我们需要求解下列问题:

n 次操作,每次操作可以±1,问把 0 变成 x 的方案数为多少。

  • 如果 n+x 是奇数,方案数为 0
  • 如果 n+x 是偶数,方案数为 (nn+x2)

组合数公式为:(nm)=n!m!(nm)!

对于1n107,可以考虑预处理 n! 的逆元(线性筛 + 前缀积),直接套公式计算。

Hint 2 : 枚举

考虑 3D 的问题,我们只需要枚举总共的 n 步,有 i 步是给 x 方向走的,那么剩余的 ni 步就是在 (y,z) 这个平面内走的,这就化归到上述的 2D 情况。

对于一个确定的 i(0in),首先要计算在 x 方向上走 i 步能否到达预定的数字,这也化归到上述的 1D 情况。此外由于一共进行了n步,那么需要将先进行的i步,分配到对应的位置,这些位置的个数为(ni)

由于组合数可以 O(1) 计算,所以本题可以在 O(n) 的时间复杂度内求解。

solution

时间复杂度:O(n)
空间复杂度: O(n)

# include <bits/stdc++.h>
# define int long long
using namespace std;
const int mo = 998244353;
const int N=1e7+10;
int s[N],t[N];
int c(int n,int m) {
	int res;
	if (n-m>=0 && n>=0 && m>=0) res = s[n]*t[m]%mo*t[n-m]%mo;
	else res = 0;
	return res;
}
int fun1(int n,int x) {
	if ((n+x)%2 != 0) return 0;
	return c(n,(n+x)/2);
}
int fun2(int n,int x,int y) {
	return fun1(n,x+y)*fun1(n,x-y)%mo;
}
signed main() {
	int n,x,y,z; cin>>n>>x>>y>>z;
	s[0]=1; for (int i=1;i<=n;i++) s[i] = s[i-1]*i%mo;
	t[1]=1; for (int i=2;i<=n;i++) t[i]=mo-mo/i*t[mo%i]%mo;
	t[0]=1; for (int i=1;i<=n;i++) t[i]=t[i-1]*t[i]%mo;
	int ans = 0;
	for (int i=0;i<=n;i++) {
		(ans += fun1(i,x) * c(n,i)%mo * fun2(n-i,y,z)%mo)%=mo;
	}
	cout<<ans<<endl;
	return 0;
}
posted @   Maystern  阅读(148)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示