您的位置:首页 > 其它

51nod 1349 最大值

2020-04-01 18:41 113 查看

题目看这里

找到每个元素g[i]作为最大值的区间[L,R],那么以他为最大值的区间数有(i-L+1)*(R-i+1)个。

为了加速,以k为最大值的区间数放入H[k],再以此统计一个前缀和,更新入H。那么>=s的区间个数就是H[1e5]-H[s-1]。

留意:为了避免区间重复,对于同样的元素,左边遇到时继续延伸,用<=号,右边遇到时不再延伸,用<号。

比如{3,3},防止既以第一个3为基准统计了区间[1,2],又以第2个3为基准统计了[1,2]。

另,统计区间数时,因为有重复元素,比如以k为最大值的区间数为cnt,那么应该是H[k]+=cnt。而非H[k]=cnt。

#include <stdio.h>
#include <string.h>

#define ll long long

const ll maxN=1e5+5;
ll N, M, K, T;

ll g[maxN], h[maxN];
ll L[maxN], R[maxN];

int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
scanf("%lld", &N);
for (ll i = 1; i <= N; ++i)
scanf("%lld", &g[i]);
scanf("%lld", &K);

for (ll i = 1; i <= N; ++i) {
L[i] = i - 1;
R[i] = i + 1;
}

for (ll i = 1; i <= N; ++i)
while (L[i] && g[L[i]] <= g[i])
L[i] = L[L[i]];
for (ll i = N; i >= 1; --i)
while (R[i] <= N && g[R[i]] < g[i])
R[i] = R[R[i]];
/*
for (ll i = 1; i <= N; ++i)
printf("%lld %lld\n", L[i], R[i]);
puts("");
*/
memset(h, 0, sizeof h);
for (ll i = 1; i <= N; ++i)
h[g[i]] += (i - L[i]) * (R[i] - i);
for (ll i = 1; i < maxN; ++i)
h[i] += h[i - 1];

for (ll i = 0, s; i < K; ++i) {
scanf("%lld", &s);
printf("%lld\n", h[maxN - 1] - h[s - 1]);
}
return 0;
}

 

转载于:https://www.cnblogs.com/Rosebud/p/9523142.html

  • 点赞
  • 收藏
  • 分享
  • 文章举报
dlsq3814 发布了0 篇原创文章 · 获赞 0 · 访问量 245 私信 关注
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: