GLLF 砍木棍
GLLF 砍木棍
题目描述
上回 GLLF 对一个木头砍了 刀,他感觉有点累了,所以他决定砍一根木棍。
他有一根长度为正整数 的木棍,把它砍成了若干个长度为正整数的小段,他很好奇有多少种砍法能使得这些小段木棍能拼成一个凸多边形。
两种砍法不同当且仅当存在砍的位置不同。我们把每段的长度按顺序放入数组,如长度为 的木棍按顺序砍出 四段,则可以表示为 。两个不同的数组代表不同的砍法。
由于这个问题的答案可能很大,请你将答案对 取模之后输出。
输入描述:
第一行一个正整数 ,表示数据组数。
接下来 行,每行一个正整数 ,表示木棍的长度。
输出描述:
对于每组数据,输出一行一个对 取模之后的整数,表示有多少种砍法。
示例1
输入
5
3
4
5
114514
1919810
输出
1
1
8
669267460
159473596
备注:
对于第三个测试用例,一种有八种切法:
解题思路
首先要知道如下性质,一个多边形是凸多边形,要满足除最长边外其余边的总长度要比最长边严格长。因此划分的方案要满足,除最大区间和外,其余区间的和要大于最大区间和,且至少要划分出 个区间。
发现直接求不好做,考虑能不能容斥,即先求出总的划分数量,再减去不合法的划分数量。
先考虑总的划分方案,由于我们需要把 划分成若干段 ,且每一段的长度至少为 ,所有段的总和恰好等于 。因此我们可以用隔板法求解,总的划分为
当然 也可以解释为,首先 个间隔每个可以选择切割或不切割,有 种方案,由于至少要有 段划分,因此至少需要切割 次。所以需要减去 以及 次切割的方案数,即 。
现在考虑不合法的划分方案。当除了最长边外,其余边的总和小于等于最长边,此时不合法。设最长边为 ,因此有 。为此我们可以枚举所有不合法的最长边 ,对于每种最长边 分为两种情况。
最长边在两端。考虑在其中一端的情况,那么剩余部分至少需要划分一次,方案数为 。因此考虑两端的话,总的划分方案就是 。
最长边不在两端,意味着两端剩余部分均不为空,不需要至少划分一次(即可以不划分)。枚举左边部分剩余的长度,那么总的方案数就是 。
因此当最长边为 时两种情况总的方案数就是 。
因此总的不合法方案数就是 ,记 。事实上对于每个查询我们不可能通过枚举 来求这个值,因此看看能否对这个求和进行化简。
把 分成 个部分。
。
。
以及 。该式可通过错位相减法进行化简。
记 ,。因此
因此 。
因此 。
因此总的合法方案数就是 。
AC 代码如下,时间复杂度为 :
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 1e9 + 7;
int qmi(int a, int k) {
int ret = 1;
while (k) {
if (k & 1) ret = 1ll * ret * a % mod;
a = 1ll * a * a % mod;
k >>= 1;
}
return ret;
}
void solve() {
int n;
cin >> n;
int m = n + 1 >> 1;
cout << ((qmi(2, n - 1) + (n - 2 * m + 1) - (n - m + 2ll) * qmi(2, n - 1 - m)) % mod + mod) % mod << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int t;
cin >> t;
while (t--) {
solve();
}
return 0;
}
参考资料
【题解】“华为杯” 2024年广东工业大学新生赛(同步赛):https://ac.nowcoder.com/discuss/1442965
本文来自博客园,作者:onlyblues,转载请注明原文链接:https://www.cnblogs.com/onlyblues/p/18588761
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效