才知道st表其实就是RMQ。。所以这玩意原来是已经学过了。。。然而也忘了。。
以前st表写得挺丑的,换了个稍微好看一点的版本,或许以后还会有更好看的版本?
然后说一下st表的基本思路就是。。倍增。。
设st[i][j]为第i位置起1<<j个数的最大or最小值。。然后直接用dp来转移就可以了。。
转移方程 st[i][j]=max(st[i][j-1],st[i+1<<(j-1)][j-1])
然后查询的时候只需要将头尾2个交叉的区间取最大or最小就可以了。。需要处理一下j的取值(当然求和不能这么干。。
然后来分析一下优缺点。。
优点十分明显。。特别好写。。然后查询只要O(1)。。不过一般没什么题会对查询有这么变态的要求吧。。
缺点也很明显。。局限性太大了。。不支持修改,而且如果要求和的话查询复杂度会上升到O(logn)。。
所以感觉。。这应该是和BIT比较互补的一种算法吧。。一个求和。。一个求最大(还不能带修!!)。。再复杂点的就要线段树了qaq
当做一个实用的小工具学着。。数据结构什么的现在是不用学那么深了。。反而要学一些小巧好写的数据结构才行。。
/**
* ┏┓ ┏┓
* ┏┛┗━━━━━━━┛┗━━━┓
* ┃ ┃
* ┃ ━ ┃
* ┃ > < ┃
* ┃ ┃
* ┃... ⌒ ... ┃
* ┃ ┃
* ┗━┓ ┏━┛
* ┃ ┃ Code is far away from bug with the animal protecting
* ┃ ┃ 神兽保佑,代码无bug
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┃
* ┃ ┗━━━┓
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛
*/
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-12
#define succ(x) (1<<x)
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define mid (x+y>>1)
#define NM 200005
#define nm 1000005
#define pi 3.1415926535897931
using namespace std;
const ll inf=998244353;
ll read(){
ll x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return f*x;
}
int st[NM][32],_st[NM][32],a[NM],_x,_y,n,m,mn[NM];
void init(){
inc(i,2,n)mn[i]=mn[i/2]+1;
inc(i,1,n)st[i][0]=_st[i][0]=a[i];
for(int j=1;succ(j)<=n;j++)
for(int i=1;i+succ(j)-1<=n;i++)
st[i][j]=max(st[i][j-1],st[i+succ(j-1)][j-1]),
_st[i][j]=min(_st[i][j-1],_st[i+succ(j-1)][j-1]);
}
int rmq(int x,int y){int k=mn[y-x];return max(st[x][k],st[y-succ(k)+1][k]);}
int _rmq(int x,int y){int k=mn[y-x];return min(_st[x][k],_st[y-succ(k)+1][k]);}
int main(){
n=read();m=read();
inc(i,1,n)a[i]=read();
init();
while(m--){
_x=read();_y=read();
printf("%d\n",rmq(_x,_y)-_rmq(_x,_y));
}
return 0;
}
Time Limit: 5000MS | Memory Limit: 65536K | |
Total Submissions: 60041 | Accepted: 28099 | |
Case Time Limit: 2000MS |
Description
For the daily milking, Farmer John's N cows (1 ≤ N ≤ 50,000) always line up in the same order. One day Farmer John decides to organize a game of Ultimate Frisbee with some of the cows. To keep things simple, he will take a contiguous range of cows from the milking lineup to play the game. However, for all the cows to have fun they should not differ too much in height.
Farmer John has made a list of Q (1 ≤ Q ≤ 200,000) potential groups of cows and their heights (1 ≤height ≤ 1,000,000). For each group, he wants your help to determine the difference in height between the shortest and the tallest cow in the group.
Input
Lines 2.. N+1: Line i+1 contains a single integer that is the height of cow i
Lines N+2.. N+ Q+1: Two integers A and B (1 ≤ A ≤ B ≤ N), representing the range of cows from A to B inclusive.
Output
Sample Input
6 3 1 7 3 4 2 5 1 5 4 6 2 2
Sample Output
6 3 0
Source
[Submit] [Go Back] [Status] [Discuss]