其他分享
首页 > 其他分享> > ABC240 G - Teleporting Takahashi

ABC240 G - Teleporting Takahashi

作者:互联网

ABC240 G - Teleporting Takahashi 题解

题目简介

给出 \(n(1\leq n \leq 10^7)\)和 \(x,y,z(-10^7\leq x,y,z \leq 10^7)\) ,求长度为 \(n+1\) 的三元组序列 \((x_i,y_i,z_i)(0 \leq i \leq n)\) 满足:

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

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

Hint 1 : 2D

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

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

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

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

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

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

组合数公式为:\(\binom{n}{m} = \frac{n!}{m!(n-m)!}\),

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

Hint 2 : 枚举

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

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

由于组合数可以 \(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;
}

标签:10,Teleporting,int,数为,ABC240,leq,return,Takahashi,pm
来源: https://www.cnblogs.com/maystern/p/15918442.html