HDU5289 Assignment
2015-07-22 16:40
155 查看
题目大意:问数组a中,区间[i,j]中最大值和最小值之差不超过k,问这样的区间有多少个。
思路:预处理出区间[i,j]中的最大值最小值(这里用的是ST算法,也有用线段树的),然后枚举左端点l,二分出符合条件的右端点r,以l为左端点,j为右端点(l<=j<=r)的符合条件的集合为(r-l+1)。
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<cmath>
#include<ctime>
#define N 100005
#define LL long long
#define mod 1000000007
#define esp 1e-6
#define y1 y1234
#define INF 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define maxn 200005
const double PI = acos(-1.0);
using namespace std;
int a
;
int mx
[21], mi
[21];
int n, k;
void RMQ(){
for (int j = 1; (1<<j) <= n; j++){
for (int i = 1; i + (1<<j)-1 <= n; i++){
int p = 1 << (j - 1);
mx[i][j] = max(mx[i][j - 1], mx[i + p][j - 1]);
mi[i][j] = min(mi[i][j - 1], mi[i + p][j - 1]);
}
}
}
int q(int i, int j){
int k = log2(j - i + 1.0);
int mma = max(mx[i][k], mx[j - (1 << k) + 1][k]);
int mmi = min(mi[i][k], mi[j - (1 << k) + 1][k]);
return mma - mmi;
}
int main(){
int t;
cin >> t;
while (t--){
cin >> n >> k;
for (int i = 1; i <= n; i++){
scanf("%d", &a[i]);
mx[i][0] = mi[i][0] = a[i];
}
RMQ();
LL ans = 0;
for (int i = 1; i <= n; i++){
int l = i, r = n;
while (l + 1 < r){
int m = (l + r) >> 1;
if (q(i, m) < k)l = m;
else r = m;
}
if (q(i, r) < k)
ans += (r * 1LL - i + 1);
else ans += (l * 1LL - i + 1);
}
cout << ans << endl;
}
return 0;
}
思路:预处理出区间[i,j]中的最大值最小值(这里用的是ST算法,也有用线段树的),然后枚举左端点l,二分出符合条件的右端点r,以l为左端点,j为右端点(l<=j<=r)的符合条件的集合为(r-l+1)。
#define _CRT_SECURE_NO_DEPRECATE
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<vector>
#include<cmath>
#include<ctime>
#define N 100005
#define LL long long
#define mod 1000000007
#define esp 1e-6
#define y1 y1234
#define INF 0x3f3f3f3f
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define maxn 200005
const double PI = acos(-1.0);
using namespace std;
int a
;
int mx
[21], mi
[21];
int n, k;
void RMQ(){
for (int j = 1; (1<<j) <= n; j++){
for (int i = 1; i + (1<<j)-1 <= n; i++){
int p = 1 << (j - 1);
mx[i][j] = max(mx[i][j - 1], mx[i + p][j - 1]);
mi[i][j] = min(mi[i][j - 1], mi[i + p][j - 1]);
}
}
}
int q(int i, int j){
int k = log2(j - i + 1.0);
int mma = max(mx[i][k], mx[j - (1 << k) + 1][k]);
int mmi = min(mi[i][k], mi[j - (1 << k) + 1][k]);
return mma - mmi;
}
int main(){
int t;
cin >> t;
while (t--){
cin >> n >> k;
for (int i = 1; i <= n; i++){
scanf("%d", &a[i]);
mx[i][0] = mi[i][0] = a[i];
}
RMQ();
LL ans = 0;
for (int i = 1; i <= n; i++){
int l = i, r = n;
while (l + 1 < r){
int m = (l + r) >> 1;
if (q(i, m) < k)l = m;
else r = m;
}
if (q(i, r) < k)
ans += (r * 1LL - i + 1);
else ans += (l * 1LL - i + 1);
}
cout << ans << endl;
}
return 0;
}
相关文章推荐
- Android的NDK开发(6)——如何定位Android NDK开发中遇到的错误
- Android的NDK开发(6)——如何定位Android NDK开发中遇到的错误
- IOS - 修改头像
- SVN Commit Failed Transaction is out of date问题
- C#基础回顾:正则表达式
- JEECMS源代码基本结构及相关技术简介
- 使用GPIO模拟I2C总线进行通信
- static、final修饰符、内部类
- POJ 1850 Code(组合数学)
- 获取系统时间,判断是时间段(早上,上午,中午,下午,晚上)
- Mysql连接数据库封装类
- 【GPU编解码】GPU硬解码---DXVA
- Day04笔记
- a+b 5
- UVA 12563 Jin Ge Jin Que Hao
- Android APP崩溃上传日志到服务器并且重启!
- synchronized详解
- Master-Mind Hints
- 【备用,Tobe continue】stm32 设置顺序等,遇过的坎儿
- 关于自己在测试行业的一些想法和自省