hdu 5289 Assignment(2015多校第一场第2题)RMQ+二分(或者multiset模拟过程)
来源:互联网 发布:阿里云给我打电话 编辑:程序博客网 时间:2024/05/17 00:14
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5289
题意:给你n个数和k,求有多少的区间使得区间内部任意两个数的差值小于k,输出符合要求的区间个数
思路:求出区间的最大最小值,只要他们的差值小于k,那么这个区间就符合要求,但是由于n较大,用暴力一定超时,所以就要用别的方法了;而RMQ是可以求区间的最值的,而且预处理的复杂度只有O(nlogn),而查询只是O(1)处理,这样相对来说节约了时间,再根据右端点来二分枚举左端点(其实不用二分好像更快,估计是数据问题)。
而另一种方法不得不说,学了C++的一定要在认真的去看一下STL的那些用法,这次用multiset来做就大大的节约时间,而且又不用思考太多,只要从左到右模拟区间,就可以了。
(RMQ+二分)代码:
#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <iostream>#include <queue>#include <algorithm>#include <vector>#include <set>using namespace std;#define LL __int64#define INF 0x3f3f3f3fconst int MAXN=100005;#define mod 1000000007int a[MAXN];LL ans;int dp1[MAXN][30],dp2[MAXN][30];void init(int n){ for(int i=1;i<=n;i++) dp1[i][0]=dp2[i][0]=a[i]; for(int j=1;(1<<j)<=n;j++) { for(int i=1;i+(1<<j)-1<=n;i++) { dp1[i][j]=max(dp1[i][j-1],dp1[i+(1<<(j-1))][j-1]); dp2[i][j]=min(dp2[i][j-1],dp2[i+(1<<(j-1))][j-1]); } }}int RMQ(int L,int R){ int k=0; while((1<<(k+1))<=R-L+1)k++; return max(dp1[L][k],dp1[R-(1<<k)+1][k])-min(dp2[L][k],dp2[R-(1<<k)+1][k]);}int binarySearch(int L,int R,int n,int k){ int mid; int l=L,r=R; while(l<=r) { mid=(l+r)/2; if(RMQ(mid,R)>=k) { l=mid+1; } else { r=mid-1; } } if(RMQ(mid,R)>=k) mid++; return mid;}int main(){ int T,i,j,n,k,mi,ma,l,r; while(~scanf("%d",&T)) { while(T--) { scanf("%d%d",&n,&k); for(i=1;i<=n;i++) scanf("%d",&a[i]); if(!k) { printf("0\n"); continue; } if(k==1) { printf("%d\n",n); continue; } init(n); ans=0; for(i=j=1;i<=n;i++) { j=binarySearch(j,i,n,k); ans+=i-j+1; } printf("%I64d\n",ans); } } return 0;}
(STL)代码:
#include <cstdio>#include <cstdlib>#include <cmath>#include <cstring>#include <iostream>#include <queue>#include <algorithm>#include <vector>#include <set>using namespace std;#define LL __int64#define INF 0x3f3f3f3fconst int MAXN=100005;#define mod 1000000007int a[100005];LL ans;int main(){ int T,i,j,n,k,mi,ma,l,r; while(~scanf("%d",&T)) { while(T--) { scanf("%d%d",&n,&k); for(i=0;i<n;i++) scanf("%d",&a[i]); if(!k) { printf("0\n"); continue; } if(k==1) { printf("%d\n",n); continue; } l=0; r=1; multiset<int>s; s.insert(a[0]); ans=n; while(1) { if(s.size()) { mi=*s.begin(); ma=*s.rbegin(); if(abs(a[r]-mi)<k&&abs(a[r]-ma)<k) { ans+=s.size(); s.insert(a[r]); r++; if(r==n) break; } else { if(s.size()) s.erase(s.find(a[l])); l++; } } else { l=r; s.insert(a[r]); r++; if(r==n) break; } } printf("%I64d\n",ans); } } return 0;}
0 0
- hdu 5289 Assignment(2015多校第一场第2题)RMQ+二分(或者multiset模拟过程)
- HDU 5289 Assignment(2015 多校第一场二分 + RMQ)
- 多校第一场 hdu 5289 Assignment(rmq+二分)
- 2015多校联合第一场5289Assignment RMQ+二分
- [RMQ+二分] 2015多校联合第一场 Assignment
- hdu 5289 Assignment(RMQ,单调队列,multiset)
- HDU 5289 Assignment (RMQ+二分)
- HDU 5289 Assignment (二分+RMQ)
- HDU 5289 Assignment(RMQ+二分)
- HDU 5289 Assignment(多校联合第一场1002)
- RMQ + 二分_______GCD(hdu 5726 2016多校第一场)
- hdu5289 Assignment(多校第一场第二题:RMQ+找规律或单调队列+找规律)
- hdu 5289 Assignment 二分+rmq
- hdu 5289(二分+RMQ) Assignment
- HDU 5289 Assignment【二分+RMQ】
- 【二分+RMQ】hdu 5289 Assignment
- 【多校第一场】【单调队列】HDU 5289 Assignment
- hdu 5289 Assignment(15多校第一场1002)
- HDU 1271 整数对-组合数学
- ionic的header颜色设置
- poj 3207 Ikki's Story IV - Panda's Trick 【2-sat 经典建模】
- 讨论“get”和“post”安全性
- Android 第3天 类的复习 图书管理 及 SQLite 基本语法
- hdu 5289 Assignment(2015多校第一场第2题)RMQ+二分(或者multiset模拟过程)
- OC_字典
- 菜鸟系列——搜索
- java GC性能优化
- Redhat6.5 配置使用centos的yum源
- 2502 月之数
- 最新Spring集成MyBatis详细教程(一)--ccw
- 将button的click事件作为判断条件
- HDU 5294 Tricks Device(多校2015 最大流+最短路啊)