高度平衡
来源:互联网 发布:win7软件停止运行 编辑:程序博客网 时间:2024/04/28 02:22
高度平衡
Time Limit:10000MS Memory Limit:65536K
Total Submit:108 Accepted:95
Case Time Limit:1000MS
Description
在每天挤奶的时候,农民约翰的N头牛(1≤n≤50000)总是排成一列。有一天,约翰决定与他的牛们一起玩一个极限飞盘游戏。为了简单起见,他将从奶牛队列里面选一定范围内的奶牛来玩这个游戏。然而所有的牛对这个游戏都很感兴趣。农民约翰列出了Q份名单(1≤Q≤200000)和每个奶牛的高度(1≤高度≤1000000)。对于每一份名单,他想你帮助他确定在每份名单中高度最高的奶牛与高度最低的奶牛的高度差是多少。
Input
第一行为N(1≤N≤50000)和Q(1≤Q≤200000);从第2行到第N+1行,每行一个数字,表示第i头牛的高度(1≤height≤1000000);从第N+2行到第N+Q+1行,每行两个整数A和B(1≤A≤B≤N),表示从第A头牛到第B头牛的范围。
Output
从第一行到第Q行,每行一个整数,表示从第A头牛到第B头牛之间,最高牛与最矮牛的高度差。
Sample Input
6 31734251 54 62 2
Sample Output
630
Source
USACO 2007 January Silver
——————————————————————————————————————————————————————————————————
法一:线段树;
#include<cstdio>const int inf=100000000;struct node{int a,b,l,r,min,max;};node tree[1000005];int tot,a[500005];int min(int x,int y){if(x<y)return x;else return y;}int max(int x,int y){if(x>y)return x;else return y;}void make(int x,int y){int i=++tot;tree[i].a=x,tree[i].b=y,tree[i].min=inf,tree[i].max=0;if(x<y){tree[i].l=tot+1;make(x,(x+y)/2);tree[i].r=tot+1;make((x+y)/2+1,y);tree[i].max=max(tree[tree[i].l].max,tree[tree[i].r].max);tree[i].min=min(tree[tree[i].l].min,tree[tree[i].r].min);}else tree[i].max=tree[i].min=a[x];}int find_min(int i,int x,int y){if(tree[i].a>y||tree[i].b<x)return inf;if(tree[i].a>=x&&tree[i].b<=y)return tree[i].min;else{int t=inf;if(tree[i].l)t=min(t,find_min(tree[i].l,x,y));if(tree[i].r)t=min(t,find_min(tree[i].r,x,y));return t;}}int find_max(int i,int x,int y){if(tree[i].a>y||tree[i].b<x)return 0;if(tree[i].a>=x&&tree[i].b<=y)return tree[i].max;else{int t=0;if(tree[i].l)t=max(t,find_max(tree[i].l,x,y));if(tree[i].r)t=max(t,find_max(tree[i].r,x,y));return t;}}int main(){int i,j,n,x,y,q;scanf("%d%d",&n,&q);for(i=1;i<=n;i++)scanf("%d",&a[i]);make(1,n);for(i=1;i<=q;i++){scanf("%d%d",&x,&y);int t,tt;t=find_min(1,x,y);tt=find_max(1,x,y);printf("%d\n",tt-t);}return 0;}法二:倍增(很经典!!!)
预处理:
dp思想:dp[i][j]表示从i起连续2^j个数中最小值(即表示区间[i,i+2^j-1]);
如;数列3,2,4,5,6,8,1,2,9,7;f[1][0]=3,f[1][1]=2,f[1][2]=2,f[1][3]=1,f[2][0]=2,f[2][1]=2,f[2][2]=2……
f[i][j]=min(f[i][j-1],f[i+2^(j-1)][j-1]);
ps:别问我怎么想到的!因为没学根本想不到,记住就好.;
询问:
区间[x,y]可以分成[x,x+2^k-1]和[y-2^k+1,y];
即f[x][k]和f[y-(1<<k)+1][k];
k=floor(log(y-x+1)/log(2));
_______________________________________________ 以下为代码表示______________________________________________________________________
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#define inf 1<<30
using namespace std;
int dpmax[50005][20],n,m,dpmin[50005][20];
int main()
{
int i,j,x,y,Max,Min,k;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)
{
scanf("%d",&dpmin[i][0]);
dpmax[i][0]=dpmin[i][0];
}
for(j=1;j<=floor(log(n)/log(2));j++)
for(i=1;i<=(n-(1<<j)+1);i++)
{
dpmin[i][j]=min(dpmin[i][j-1],dpmin[i+(1<<(j-1))][j-1]);
dpmax[i][j]=max(dpmax[i][j-1],dpmax[i+(1<<(j-1))][j-1]);
}
for(i=1;i<=m;i++)
{
Max=0;Min=inf;
scanf("%d%d",&x,&y);
k=floor(log(y-x+1)/log(2));
Max=max(dpmax[x][k],dpmax[y-(1<<k)+1][k]);
Min=min(dpmin[x][k],dpmin[y-(1<<k)+1][k]);
printf("%d\n",Max-Min);
}
return 0;
}
- 高度平衡
- 高度平衡树 -- AVL 树
- 高度平衡的二叉树
- 平衡二叉树计算高度的同时判断是否平衡
- LeetCode之判断高度平衡二叉树
- AVL(高度平衡的二叉树)
- 判断二叉树是否平衡,计算树的高度
- BinaryTree的高度求解及平衡树判断
- 【数据结构】AVLTree(高度平衡的二叉搜索树)
- 高度平衡的二叉树——AVLTree
- 高度平衡的二叉搜索树-----AVL树
- 高度平衡二叉树——AVL树
- 【LeetCode笔记】Balanced Binary Tree 高度平衡二叉树
- AVL树(高度平衡的二叉搜索树)平衡因子的调节和旋转
- 平衡
- 平衡
- 【平衡】
- 平衡
- 在 XML 中通过数据绑定用一行代码定制字体
- 初识移动端跨平台(JavaScript篇)
- Dubbo架构设计详解
- 教主Baby大婚能收多少份子钱?
- Reading and Writing using a Large Random Access File
- 高度平衡
- 成为核心程序员的一些建议
- 如何在lua中打印一个数组(table)
- PHP CLI 模式详解
- nodeJs mongodb凭据验证
- LintCode: 最大子数组
- 根据两点经纬坐标计算两点间的距离[JAVA]
- JAVA模拟微信消息发送请求
- c++类中静态函数不能调用类中的非静态函数原因