2 条题解
-
1
借此题介绍一种打在线比赛快速过规律题的技巧。本题解没有严谨证明,想看证明请移步其他题解。
首先写出暴力程序:
#include <bits/stdc++.h> using namespace std; typedef long long ll; ll a[100005]; int main() { int t; cin >> t; while(t--) { int n,k,d; cin >> n >> k >> d; a[1] = k; for(int i = 2;i <= n;i++) a[i] = a[i-1] + d; ll num = 0; for(ll i = 1;i <= n;i++) { for(ll j = i;j <= n;j++) { ll sum = 0; for(int k = i;k <= j;k++) sum += a[k]; if(sum % (j-i+1) == 0) num++; } } cout << num << endl; } return 0; }
此时提交可以获得 分的高分。
看部分分:此时 。
那么我们先将所有的 和 输入,容易发现 的值和答案没有关系。
那么我们接着将 和 输入,得到如下式子:
如果你瞪眼能力强,那么应该可以看出答案了。但是,如果没看出来呢?我们可以使用一个在线查询数列的网站 oeis.org,进入后在输入框输入 ,根据查询结果我们可以得到通项为 ,于是我们就可以拿到这档部分分了。此时能拿到 分。
那么让我们将这种结论继续扩展:还是用之前的暴力程序,取 进行求解。可以发现,令 ,当 时,答案相同;当 时,答案也相同。那么当 时,显然答案和上面 时答案相同;于是我们取 求解,这个数列很好瞪出来(看不出来,同理使用
OEIS
即可),通项公式即为 。那么我们只需判断一下 的奇偶性即可。至此,我们在本题获得了 分。时间复杂度 。
#include <bits/stdc++.h> using namespace std; int main() { int t; cin >> t; while(t--) { int n,k,d; cin >> n >> k >> d; cout << (d % 2 ? 1ll * (n+1) * (n+1) / 4 : 1ll * (n+1) * n / 2) << endl; } return 0; }
信息
- ID
- 65
- 时间
- 3000ms
- 内存
- 512MiB
- 难度
- 2
- 标签
- 递交数
- 382
- 已通过
- 107
- 上传者