题目大意:有$n$根竹竿,第$i$根竹竿在$i$位置,第$i$根竹竿高度为$h_i$,每根竹竿可以向左倒或向右倒,问有几对竹竿倒下后顶端重合。
题解:求出每根竹竿倒下后的位置,离散化,记录一下每个点出现次数就行了
卡点:没开$long;long$
C++ Code:
#include <cstdio> #include <algorithm> #define maxn 200010 int n, m; int l[maxn], r[maxn]; int v[maxn << 1], tot; long long cnt[maxn << 1], ans; int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { int a; scanf("%d", &a); v[++tot] = l[i] = i - a; v[++tot] = r[i] = i + a; } tot = (std::sort(v + 1, v + tot + 1), std::unique(v + 1, v + tot + 1) - v - 1); for (int i = 1; i <= n; i++) { l[i] = std::lower_bound(v + 1, v + tot + 1, l[i]) - v; r[i] = std::lower_bound(v + 1, v + tot + 1, r[i]) - v; ans += cnt[l[i]]; if (l[i] != r[i]) { ans += cnt[r[i]]; cnt[r[i]]++; } cnt[l[i]]++; } printf("%lld ", ans); return 0; }