中国地质大学(武汉)第十九届程序设计大赛 - B - 圣杯地牢
通过题意可以发现,每次操作就是在数组 \(a\) 中选择一个点,然后以它为起点进行区间加值操作 (注意是整个数组都会加,最终以当前点的前一个点结束)
判断是否可以通过一些操作使的从数组 \(a\) ,变为数组 \(b\)。
首先可以令 \(c_i = b_i - a_i\),问题转换为是否可以通过 有限次操作,将数组 \([0,0,0, \dots , 0]\) 转化为数组 \(c\)
通过观察可以发现,每次操作对于数组的和的增量是固定的,即 \(\delta sum = \sum_{i=1}^{n}i = (n + 1) \times n / 2\)
那么首先可以进行一个判断, 即 \(\sum_{i=1}^{n} c_i \; \% \; (\delta sum) == 0\), 令 \(cnt = \sum_{i=1}^{n} c_i \; / \; (\delta sum)\)
然后我们可以发现,每次操作对于起点来说,他的差分值的增量为 \(\delta d = (1-n)\) ,假设第 \(i\) 个点的操作次数为 \({opt}_i\),那么 \(cnt\) 次操作之后,第 \(i\) 个点的差分值增量为 \(\delta d = (1-n) \times {opt}_i + (cnt - {opt}_i)\)
可得一个等式 \(\sum_{i=1}^{n} {opt}_i = cnt\)
假设数组 \(d\) 为数组 \(c\) 的差分数组
\[(1-n) \times {opt}_i + cnt - {opt}_i = d_i
\]
\[cnt - n \times {opt}_i = d_i
\]
\[{opt}_i = \frac{cnt - d_i}{n}
\]
因此我们可以通过判断上述 \(n + 1\) 个式子是否有整数解即可。
// Problem: 圣杯地牢
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/35753/B
// Memory Limit: 262144 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, b) for(int i(a); i <= b; i ++)
#define dec(i, a, b) for(int i(a); i >= b; i --)
#ifdef LOCAL
#include <debugger>
#else
#define debug(...) 42
#endif
template <typename T> inline void chkmax(T &x, T y) { x = max(x, y); }
template <typename T> inline void chkmin(T &x, T y) { x = min(x, y); }
constexpr int N = 100010;
ll a[N], b[N];
ll d[N];
ll sum;
void solve() {
int n; cin >> n;
rep(i, 1, n) cin >> a[i];
rep(i, 1, n) cin >> b[i], b[i] -= a[i], sum += b[i];
rep(i, 1, n) if(b[i] < 0) {
cout << "NO\n";
return ;
}
ll all = 1ll * n * (n + 1) / 2;
if(sum % all || sum < all) {
cout << "NO\n";
return ;
}
ll cnt = sum / all;
rep(i, 1, n) {
d[i] = b[i] - b[i - 1];
if(i == 1) d[i] -= b[n];
ll res = (1 - n) * (cnt - d[i]);
if((cnt - d[i]) % n) {
cout << "NO\n";
return;
}
res /= n;
res += cnt;
ll res1 = (cnt - d[i]) / n;
if(res - res1 != d[i]) {
cout << "NO\n";
return;
}
}
cout << "YES\n";
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
solve();
return 0;
}
/*
*
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████+
* ◥██◤ ◥██◤ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃ + + + +Code is far away from
* ┃ ┃ + bug with the animal protecting
* ┃ ┗━━━┓ 神兽保佑,代码无bug
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/