ST表
2017-12-15 19:16
92 查看
最近几天有大佬给蒟蒻我讲了数据结构,于是趁机水一篇博客。。。
提供ST表模板的链接:洛谷P3865传送门
首先,预处理一下2的n次方,n一般小于20。
再预处理一个数组,lg[i]表示不大于i的最大的2的幂的指数(请读者反复阅读这句拗口的话)。
最后只需要DP求一波区间最值了。
预处理写完以后,查询操作就很简单了,找到被包含在要查询区间的两个已经预处理过的区间,比较一下求个最值就好了。
能看到这里的都是真爱,感谢各位老爷,给跪了orz。
最后附上方便复制粘贴的代码:
知道了原理看这个代码真的很简单,博主也主要是记个笔记,然后给那些知道原理,但是代码能力不足,或者一直莫名WA的小伙伴的,还请各位读者老爷谅解。
ST表是一个强大的静态区间最值离线查询算法,处理完数据以后查询的复杂度仅为O(1),有得必有失,像介绍的一样,ST表仅支持离线查询(即无法修改数据的值,无法添加/删除数据),原理很简单,博主也懒得画图,网上也找不到比较好的带图的详解(有兴趣的小伙伴可以自己去搜一下ST表的讲解)所以果断讲代码。。。(不要打我)提供ST表模板的链接:洛谷P3865传送门
首先,预处理一下2的n次方,n一般小于20。
pao[0]=1; for(int i=1;i<=18;i++) { pao[i]=pao[i-1]<<1;//位运算,等价于乘2 }
再预处理一个数组,lg[i]表示不大于i的最大的2的幂的指数(请读者反复阅读这句拗口的话)。
for(int i=2;i<=n;i++) { lg[i]=lg[i/2]+1;//稍微用了一下数学技巧 }
最后只需要DP求一波区间最值了。
int a=1,b=1; int hehe=lg ;//为了减少循环次数加的小优化,针对较小数据有用 for(int i=1;i<=hehe;i++) { a<<=1; for(int j=1;j<=n-a+1;j++) {//依然是减少循环次数的优化,如果数组开的够大的话不影响结果 //但是对于大数据会多耗很多时间,知道原理的小伙伴仔细想想就能理解 st[j][i]=max(st[j][i-1],st[j+b][i-1]); //蜜汁状态转移方程,合并两个区间的最大值 } b<<=1; }
预处理写完以后,查询操作就很简单了,找到被包含在要查询区间的两个已经预处理过的区间,比较一下求个最值就好了。
int find(int a,int b) { int x=lg[b-a]; int c=pao[x];//这里就需要我们预处理出来的数据才能实现O(1)复杂度 int ans=max(st[a][x],st[b-c+1][x]); return ans; }
能看到这里的都是真爱,感谢各位老爷,给跪了orz。
最后附上方便复制粘贴的代码:
#include<bits/stdc++.h> using namespace std; int pao[20]; int lg[100005]; int st[200005][20]; int find(int a,int b) { int x=lg[b-a]; int c=pao[x]; int ans=max(st[a][x],st[b-c+1][x]); return ans; } int main() { int n,m; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d",&st[i][0]); } pao[0]=1; for(int i=1;i<=18;i++) { pao[i]=pao[i-1]<<1; } for(int i=2;i<=n;i++) { lg[i]=lg[i/2]+1; } int a=1,b=1; int hehe=lg ; for(int i=1;i<=hehe;i++) { a<<=1; for(int j=1;j<=n-a+1;j++) { st[j][i]=max(st[j][i-1],st[j+b][i-1]); } b<<=1; } for(int i=1;i<=m;i++) { scanf("%d%d",&a,&b); printf("%d\n",find(a,b)); } return 0; }
相关文章推荐
- hdu 5443 The Water Problem(求区间最值+ST表)
- Codevs 4373 窗口(线段树 单调队列 st表)
- HDU5289:Assignment(二分 + ST表)
- ST表模板
- BZOJ 3230 相似子串 | 后缀数组 二分 ST表
- BZOJ_1067_[SCOI2007]降雨量_ST表
- ST表学习
- codeforces 713D 二维ST表维护最大值
- 玲珑杯oj1149区间最大值最小值--st表
- luogu P3865 【模板】ST表
- [洛谷P3865] ST表
- 模板 ST表
- 【bzoj4540】【HNOI2016】【序列】【莫队+st表】
- st表
- poj 3264 (summerIII O) j树状数组 ST表(区间最值查询)
- ST表
- [luoguP2463] [SDOI2008]Sandy的卡片(后缀数组 + st表)
- HDU5726 GCD(二分 + ST表)
- 【bzoj 1012】[JSOI2008]最大数maxnumber(线段树||st表)
- ST表模板