比赛链接:
https://atcoder.jp/contests/abc255
E - Lucky Numbers
题意:
给定长为 \(n - 1\) 的序列 \(s\) 以及 \(m\) 个不同的幸运数。
要求构造一个序列 \(a\),对于 \(1 <= i <= n - 1\),\(a_i + a_{i + 1} = s_i\),问这个序列中最多能有多少个幸运数。
思路:
如果 \(a_1\) 确定了,那么可以得到
\(a_1 = a_1\)
\(a_2 = s_1 - a_1\)
\(a_3 = s_2 - a_2 = s_2 - s_1 + a_1\)
.
.
.
所以整个 \(a\) 序列都被确定了。
构造一个 \(b\) 序列,\(b_1 = 0,b_i = s_i - b_{i - 1} \in (2 <= i <= n)\)。
如果第 \(i\) 个数为第 \(j\) 个幸运数,\(a_i = (-1)^{i + 1} a_1 + b_i = x_j\),推得 \(a_1 = (-1)^{i + 1} (x_j - b_i)\)。
所以通过 \(j * i\) 的遍历,统计最多的数量即可。
代码:
#include <bits/stdc++.h>
using namespace std;
#define LL long long
int main(){
ios::sync_with_stdio(false);cin.tie(0);
LL n, m;
cin >> n >> m;
vector <LL> s(n), x(m + 1), b(n + 1);
for (int i = 1; i <= n - 1; i ++ )
cin >> s[i];
for (int i = 1; i <= m; i ++ )
cin >> x[i];
for (int i = 2; i <= n; i ++ )
b[i] = s[i - 1] - b[i - 1];
map <LL, LL> mp;
for (int j = 1; j <= m; j ++ )
for (int i = 1; i <= n; i ++ ){
if (i & 1)
mp[x[j] - b[i]] ++ ;
else
mp[b[i] - x[j]] ++ ;
}
LL ans = 0;
for (auto x : mp)
ans = max(ans, x.second);
cout << ans << "\n";
return 0;
}