[洛谷P4889]kls与flag

题目大意:有$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\n", ans);
	return 0;
}

  

posted @ 2018-09-25 20:32  Memory_of_winter  阅读(244)  评论(0)    收藏  举报