HDU 5289 Assignment (二分+RMQ) 2015多校训练一 1002
2015-07-22 11:19
423 查看
假设右端点r固定,那么如果能找到离得最远的一个l,使l到r满足要求,那么[l+1~r],[l+2~r].....都满足要求。所以可以枚举右端点,去找最远的满足条件的左端点,使满足条件,答案就是把这些长度求和。
因为序列是静态的,所以可以用ST算法在log n时间求出任意区间内的最大,最小值,然后用这些值二分求解最远的l。
代码:
因为序列是静态的,所以可以用ST算法在log n时间求出任意区间内的最大,最小值,然后用这些值二分求解最远的l。
代码:
#include <iostream> #include <cstdio> #include <cstring> using namespace std; #define LL long long int N,k; int a[100005]; int mx[100005][20]; int mi[100005][20]; void RMQ_init(){ for(int i=0;i<N;i++){ mx[i][0]=a[i]; mi[i][0]=a[i]; } for(int j=1;(1<<j)<=N;j++){ for(int i=0;i+(1<<j)-1<N;i++){ mx[i][j]=max(mx[i][j-1],mx[i+(1<<(j-1))][j-1]); mi[i][j]=min(mi[i][j-1],mi[i+(1<<(j-1))][j-1]); } } } int RMQx(int L,int R){ int k=0; while((1<<(k+1)) <=R-L+1) k++; return max(mx[L][k],mx[R-(1<<k)+1][k]); } int RMQi(int L,int R){ int k=0; while((1<<(k+1)) <=R-L+1) k++; return min(mi[L][k],mi[R-(1<<k)+1][k]); } int BS(int pos){ int l=0,r=pos; int res=pos; while(r>=l){ int mid=(l+r)/2; if(RMQx(mid,pos)-RMQi(mid,pos)<k){ res=mid; r=mid-1; } else l=mid+1; } return res; } int main(){ int T; scanf("%d",&T); while(T--){ scanf("%d%d",&N,&k); for(int i=0;i<N;i++){ scanf("%d",&a[i]); } RMQ_init(); LL res=0; for(int i=0;i<N;i++){ //cout<<px<<' '<<pi<<endl; int pos=BS(i); res+=(i-pos+1); } printf("%I64d\n",res); } return 0; }
相关文章推荐
- LocalThread分析
- document.referrer的使用和window.opener 跟 window.parent 的区别
- JSF笔记----方法表达式加入参数
- 我的工作笔记之第一篇 (星云)
- C# vs 2015 to automate ONE
- 数据库主体在该数据库中拥有 架构,无法删除。
- oracle用户创建及权限设置
- 【C++】智能指针(Smart Pointer)
- 利用Eclipse构建Spark集成开发环境
- mac用pip安装numpy, scipy, scikit-learn
- centos下删除大文件
- js获取input file完整路径的方法
- java 编程小技巧
- Android 离线播放 (HLS)m3u8文件
- animation几个比较好玩的属性(alternate,及animation-fill-mode)
- Rails中的使用者验证:Devise
- 招聘管理
- 为网站添加ico图标
- 回文串(杭州电2029)
- Win7没有telnet怎么办