您的位置:首页 > 其它

51nod 1275 连续子段的差异

2020-04-01 18:40 113 查看

题目看这里

若[i,j]符合要求,那么[i,j]内的任何连续的子段都是符合要求的。我们可以枚举i,找到能合格的最远的j,然后ans+=(j-i+1)。

那么问题就转换成了:在固定i的情况下,如何判断j范围内是否合法?若[i,j]内的max-min<=K自然就合法。于是相当于求区间内的最值问题。这个可以用单调队列解决。

下面对代码给出一些解释:

1:为何是j-i而非j-i+1?因为当不合法时区间相当于[i,j),左闭右开,数量是i-j即可。

2:后面的两行如if (dqB.front() == i) dqB.pop_front(); 什么作用?因为要枚举i,所以到了下一个i的时候,若前面的i还在队列中,要去掉。

#include <bits/stdc++.h>
using namespace std;

const int maxN=5e4+5;
int N, M, K, T;
int g[maxN];
deque<int> dqB, dqS;

int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
scanf("%d%d", &N, &K);
for (int i = 1; i <= N; ++i)
scanf("%d", g + i);
int ans = 0;
for (int i = 1, j = 1; i <= N; ++i) {
while (j <= N) {
while (dqS.size() && g[dqS.back()] >= g[j]) dqS.pop_back();
dqS.push_back(j);
while (dqB.size() && g[dqB.back()] <= g[j]) dqB.pop_back();
dqB.push_back(j);

if (g[dqB.front()] - g[dqS.front()] > K)
break;
++j;
}
ans += (j - i);
if (dqS.front() == i) dqS.pop_front();
if (dqB.front() == i) dqB.pop_front();
}
printf("%d", ans);
return 0;
}

附上别的相关的博客

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

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