Sol 函数求值
函数求值
Contents
题面描述
给定函数:
\[f(x) = \begin {cases}
1 & x \lt 4 \\
f(x - 1) + f(x - \pi) & x \ge 4
\end{cases}
\]
此处 \(\pi = 3.1415926\)。
给定 \(x\),问 \(f(x) \texttt{ mod 998244353}\) 的值。
输入格式
一个正整数 \(x (1 \le x \le 2 \times 10^5)\)
输出格式
输出一个数字表示答案。
样例#1
样例输入#1
4
样例输出#1
2
样例#2
样例输入#2
25
样例输出#2
4024
Analysis
\(\texttt{10pts 的暴力想法}\)
考虑给了个一眼式子,那我们可以随便搞搞,然后就幻想一下,就 \(\texttt{10pts}\) 了。
看个乐呵
// _____ _ _ _____ _____ _
// | ___| _ _ __| |_| |__ __|___ |___ |__ __ _ __| |
// | |_ | | | | '__| __| '_ \ / _ \ / / / / _ \ / _` |/ _` |
// | _|| |_| | | | |_| | | | __// / / / (_) | (_| | (_| |
// |_| \__,_|_| \__|_| |_|\___/_/ /_/ \___/ \__,_|\__,_|
// _ _______ _____ ____ ___ _____ ____
// | |/ / ____| ____| _ \ |_ _|_ _| / ___|
// | ' /| _| | _| | |_) | | | | | | | _
// | . \| |___| |___| __/ | | | | | |_| |
// |_|\_\_____|_____|_| |___| |_| \____|
#include <bits/stdc++.h>
#define pi 3.1415926
#define ll unsigned long long
#define md 998244353
using namespace std;
int n; map <double, int> mp;
int f(double x) { // 这个 map 用了跟没用一样
if (x < 4) return 1;
if (mp[x]) return mp[x];
ll res = (f(x - 1) + f(x - pi)) % md;
mp[x] = (int)res;
return mp[x];
} signed main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0); cin >> n;
cout << f(n * 1.0); return 0;
}
但是,距离这道题的期望得分,仍然差了一个 \(\texttt{0}\) 所以,还要继续想。
题意转化
我们通过观察式子,然后……感性的理解一下,发现:
数轴零点上,一只小粉兔,向正方向,跳跳跳,有俩种步长:\(\texttt{1 和 } \pi\) 他跳到 \(n - 4\) 的点停了,求方案数
正解
考虑做一个预处理算组合数,害怕 \(TLE\) 警告,用下逆元,然后枚举走了 \(i\) 个 \(1\) 步,可以算出走了几个 \(\pi\) 步。
然后处理一个细节,最后一步走个啥?
考虑算一下小粉兔跳完之后,肯定会超出 \(n - 4\) 这个点,问下他超了多少,若超过 \(1\) 就说明,最后一步必然跳的是 \(\pi\),反之自证。
于是可以写转移了:
\[ans += \begin {cases}
C_{\texttt{总步数}} ^ {走 1 步} & x \le 1 \\
\\
C_{\texttt{总步数 - 1}} ^ {走 \pi 步 - 1} & x \gt 1\\
\end {cases}
\]
解释一下上述转移的细节:
- 第一种是总步数里面挑出走 \(1\) 的。
- 第二种是不算最后一步里面挑出走 \(\pi\) 的。
- 关于为啥 \(case\#2\) 里 \(-1\) 了,请阅读上文讨论的细节。
毕。
// _____ _ _ _____ _____ _
// | ___| _ _ __| |_| |__ __|___ |___ |__ __ _ __| |
// | |_ | | | | '__| __| '_ \ / _ \ / / / / _ \ / _` |/ _` |
// | _|| |_| | | | |_| | | | __// / / / (_) | (_| | (_| |
// |_| \__,_|_| \__|_| |_|\___/_/ /_/ \___/ \__,_|\__,_|
// _ _______ _____ ____ ___ _____ ____
// | |/ / ____| ____| _ \ |_ _|_ _| / ___|
// | ' /| _| | _| | |_) | | | | | | | _
// | . \| |___| |___| __/ | | | | | |_| |
// |_|\_\_____|_____|_| |___| |_| \____|
init();
/* ... ... */
if (n < 4) {cout << 1; return 0;}
for (int i = 0; i <= n - 3; i++) {
int j = ceil(((double)(n - 4) - i) / pi);
int dt = ceil((double)j * pi - (double)(n - 4) + i);
if (dt <= 1) ans = (ans + C(i + j, i)) % md;
else ans = (ans + C(i + j - 1, j - 1)) % md;
}
/* ... ... */

浙公网安备 33010602011771号