poj3264——Balanced Lineup(ST算法及线段树操作)
2010-09-28 16:09
295 查看
dp[i][j]
表示
[i,j]
区间内的最小值,则
•
dp[i][i]=a[i]
•
•
dp[i][j]=min{dp[i][j-1],dp[i+2^(j-1)][j-1]}。
•
如果询问区间为
[s,t]
,
则只需要取
k=(int)log2(t-
s+1)
•
RMQ[s,t]=min{dp[s][k],dp[t-2^k+1][k]}。
此题,还可以运用线段树来求得,贴上刚学的线段树ac代码:
表示
[i,j]
区间内的最小值,则
•
dp[i][i]=a[i]
•
•
dp[i][j]=min{dp[i][j-1],dp[i+2^(j-1)][j-1]}。
•
如果询问区间为
[s,t]
,
则只需要取
k=(int)log2(t-
s+1)
•
RMQ[s,t]=min{dp[s][k],dp[t-2^k+1][k]}。
#include<stdio.h> #include<string.h> #include<math.h> #define max 500005 int a[max]; int fmin[max][50],fmax[max][50]; int n,q; int f_min(int a,int b) { return a<b?a:b; } int f_max(int a,int b) { return a>b?a:b; } void st() { int m,i,j,k; k=(int)(log((double)(n))/log(2.0)); for(j=1;j<=k;j++) { for(i=1;i+(1<<j)-1<=n;i++) { fmin[i][j]=f_min(fmin[i][j-1],fmin[i+(1<<(j-1))][j-1]); fmax[i][j]=f_max(fmax[i][j-1],fmax[i+(1<<(j-1))][j-1]); } } } int find(int a,int b) { int fax,fin,k; k=(int )(log((double)(b-a+1))/log(2.0)); fax=f_max(fmax[a][k],fmax[b-(1<<k)+1][k]); fin=f_min(fmin[a][k],fmin[b-(1<<k)+1][k]); return fax-fin; } int main() { int i; scanf("%d%d",&n,&q); for(i=1;i<=n;i++) { scanf("%d",&a[i]); fmin[i][0]=a[i]; fmax[i][0]=a[i]; } st(); while(q--) { int a,b; scanf("%d%d",&a,&b); printf("%d/n",find(a,b)); } return 0; }
此题,还可以运用线段树来求得,贴上刚学的线段树ac代码:
#include<stdio.h> #include<string.h> #define MAX 0 #define MIN 1000000 struct node { int left,right; int min,max; }tree[150000]; int n,min,max; void create(int l,int r,int index)//初始化 { int mid; tree[index].left =l; tree[index].right=r; tree[index].max =MAX; tree[index].min =MIN; if(l==r) return ; mid=(l+r)/2; create(l,mid,index*2);//左子树 create(mid+1,r,index*2+1);//右子树 } void insert(int l,int r,int index,int p,int d) { int mid=0; if(l<=p&&p<=r)//p在此线段里 { if(tree[index].max <d) tree[index].max =d; if(tree[index].min >d) tree[index].min =d; } if(l==r)//操作到子节点,结束 return ; mid=(l+r)/2; if(mid>=p) insert(l,mid,index*2,p,d);//对左子树更新 else insert(mid+1,r,index*2+1,p,d);//对右子树更新 } void research(int l,int r,int index,int a,int b)//寻找操作 { int mid; if(l==a&&r==b)//刚好为一个区间 { if(tree[index].max >max) max=tree[index].max ; if(tree[index].min<min) min=tree[index].min ; return ; } if(l==r)//同样子节点结束 return ; mid=(l+r)/2; if(mid>=b)//在左半边 research(l,mid,index*2,a,b); else if(mid<a)//在右半边 research(mid+1,r,index*2+1,a,b); else//实现跨越的查找 { research(l,mid,index*2,a,mid); research(mid+1,r,index*2+1,mid+1,b); } } int main() { int q,i,a; scanf("%d%d",&n,&q); create(1,n,1); for(i=0;i<n;i++) { scanf("%d",&a); insert(1,n,1,i+1,a); } int b; while(q--) { scanf("%d%d",&a,&b); min=MIN;max=MAX; research(1,n,1,a,b); printf("%d/n",max-min); } return 0; }
相关文章推荐
- poj 3264 小白算法练习 Balanced Lineup 线段树
- 【POJ 3264】Balanced Lineup(RMQ算法||线段树)
- POJ 3264 Balanced Lineup-初入算法 线段树
- POJ 3264 Balanced Lineup (ST算法入门)
- poj 3264(线段树 || ST(Sparse Table)算法)
- POJ3264 - Balanced Lineup (线段树 基本操作)
- Poj 3264 Balanced Lineup【RMQ----ST算法】
- [POJ 3264]Balanced Lineup(ST算法求RMQ)
- POJ 3264 Balanced Lineup (RMQ线段树)
- POJ 3264 Balanced Lineup(RMQ 线段树)
- (转)POJ 3264 - Balanced Lineup (线段树)
- poj 3264 Balanced Lineup(线段树 区间最值)
- POJ 3264 Balanced Lineup(第一道线段树)
- POJ 3264 线段树 ST
- poj 3264 Balanced Lineup 线段树
- POJ 3264-Balanced Lineup详解(线段树区间求值)
- poj 3264 Balanced Lineup(基础线段树)
- POJ 3264 Balanced Lineup(简单线段树)
- POJ 3264 Balanced Lineup -- RMQ或线段树
- poj 3264 Balanced Lineup (线段树)