poj3264(st表模板)

才知道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;
}





Balanced Lineup
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

Line 1: Two space-separated integers, N and Q.
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 ≤ ABN), representing the range of cows from A to B inclusive.

Output

Lines 1.. Q: Each line contains a single integer that is a response to a reply and indicates the difference in height between the tallest and shortest cow in the range.

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]


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值