题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6701

题目大意为求满足 $max(a_{l},a_{l+1}\cdot \cdot \cdot a_{r})-(r-l+1)<=k$的区间个数。

先预处理出前缀最大值和后缀最大值和ST表,然后分治。

每次可以得到这次分治区间的区间最大值,然后我们要求出以该最大值为区间最大值时的合法区间数目。

这里我们可以枚举合法区间的左端点(右端点),然后通过化简上式得到合法的右端点(左端点),选择枚举左还是右端点由当前区间最大值的位置所决定,因为左端点一定在最大值左边,右端点一定在最大值右边,所以选择数量较小的一边来枚举。

 #include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<set>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 3e5 + ;
int a[maxn], pos[maxn], L[maxn], R[maxn], Log[maxn];
int n, k;
int dp[maxn][];
int query(int l, int r) {
int k = Log[r - l + ];
if (a[dp[l][k]] > a[dp[r - ( << k) + ][k]])
return dp[l][k];
else
return dp[r - ( << k) + ][k];
}
ll dfs(int l, int r) {
if (l == r)return a[l] - <= k;
if (l > r)return ;
int cnt = query(l, r);
ll ans = ;
if (cnt - l < r - cnt) {
for (int i = l; i <= cnt; i++) {
int ls = max(cnt, i + a[cnt] - k - );
int rs = min(r, R[i]);
if (rs >= ls)
ans += rs - ls + ;
}
}
else {
for (int i = cnt; i <= r; i++) {
int ls = max(l, L[i]);
int rs = min(i - (a[cnt] - k) + , cnt);
if (rs >= ls) ans += rs - ls + ;
}
}
return ans + dfs(l, cnt - ) + dfs(cnt + , r);
}
int main() {
int t;
scanf("%d", &t);
while (t--) {
scanf("%d%d", &n, &k);
for (int i = ; i <= n; i++)
scanf("%d", &a[i]);
Log[] = -;
for (int i = ; i <= n; i++) Log[i] = Log[i >> ] + ;
for (int i = ; i <= n; i++)
dp[i][] = i;
for (int j = ; ( << j) <= n; j++) {
for (int i = ; i + ( << j) - <= n; i++) {
if (a[dp[i][j - ]] > a[dp[i + ( << (j - ))][j - ]])
dp[i][j] = dp[i][j - ];
else
dp[i][j] = dp[i + ( << (j - ))][j - ];
}
}
for (int i = ; i <= n; i++)pos[i] = ;
R[n + ] = n;
for (int i = n; i >= ; i--) {
if (pos[a[i]]) {
R[i] = pos[a[i]] - ;
pos[a[i]] = i;
}
else {
pos[a[i]] = i;
R[i] = n;
}
R[i] = min(R[i], R[i + ]);
}
for (int i = ; i <= n; i++)pos[i] = ;
for (int i = ; i <= n; i++) {
if (pos[a[i]]) {
L[i] = pos[a[i]] + ;
pos[a[i]] = i;
}
else {
pos[a[i]] = i;
L[i] = ;
}
L[i] = max(L[i], L[i - ]);
}
printf("%lld\n", dfs(, n));
}
}

最新文章

  1. openresty 前端开发入门五之Mysql篇
  2. WebApi安全性 使用TOKEN+签名验证
  3. C#调用win32 api程序实例
  4. 安装rabbitMQ delayed-messaged
  5. poj-1611-The Suspects
  6. CSS布局--浮动与清除
  7. android 开发Parcelable 怎么传值ArrayList
  8. CSAPP(1):数字的计算机表示——课后题
  9. quartus II 自动生成testbench
  10. JQuery ajax调用asp.net的webMethod
  11. 在jsp中用一数组存储了数据库表中某一字段的值,然后在页面中输出其中的值。
  12. 【个人笔记】《知了堂》前端mySql基础
  13. 查看主机DNSserver
  14. 201421123042 《Java程序设计》第9周学习总结
  15. 在网络编程中的io流小问题
  16. elasticsearch的CPU居高不下的问题
  17. idea 方便的设置代码段
  18. MySQL--运维内参中的binlog_summary脚本
  19. 【资料收集】PCA降维
  20. 如何开发一个基于 Docker 的 Python 应用

热门文章

  1. Oracle 9i,10g,11g各自alert日志的位置
  2. IO初步
  3. 【NOIP2013模拟】归途与征程
  4. ubuntu16.04 下 C# mono开发环境搭建
  5. PHP入门培训教程 PHP 数据类型
  6. jsp大文件下载+断点续传
  7. java读取ldif文件并创建新的节点
  8. 判断内网机器的真实外网IP或域名的方法总结
  9. es的调优
  10. GPG(pgp)加解密中文完整教程