http://poj.org/problem?id=3264
題意:輸入n個數,有m個詢問,每個詢問輸入l,r,求區間[ l , r ]之間最大數與最小數之差。
思路:
我用的線段樹過的,節點增加兩個域,分別記錄該區間的最大值和最小值。然後設置全局變量maxh和minh動態維護區間[ l, r]中的最大值和最小值。
不過線段樹過時間不是一般的慢,3s+。。。
#include#include #include using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 50005; struct line { int l; int r; int minh; int maxh; }tree[maxn<<2]; int a[maxn]; int maxh; int minh; void build(int v, int l, int r) { tree[v].l = l; tree[v].r = r; if(l == r) { tree[v].maxh = a[l]; tree[v].minh = a[l]; return; } int mid = (l+r)>>1; build(v*2,l,mid); build(v*2+1,mid+1,r); tree[v].maxh = max(tree[v*2].maxh,tree[v*2+1].maxh); tree[v].minh = min(tree[v*2].minh,tree[v*2+1].minh); } void query(int v, int l, int r) { if(tree[v].l == l && tree[v].r == r) { maxh = max(maxh,tree[v].maxh); //maxh,minh動態維護 minh = min(minh,tree[v].minh); return; } int mid = (tree[v].l+tree[v].r)>>1; if(r <= mid) query(v*2,l,r); else { if(l > mid) query(v*2+1,l,r); else { query(v*2,l,mid); query(v*2+1,mid+1,r); } } } int main() { int n,m; scanf("%d %d",&n,&m); for(int i = 1; i <= n; i++) scanf("%d",&a[i]); build(1,1,n); int l,r; while(m--) { scanf("%d %d",&l,&r); maxh = 0; minh = INF; //不要忘記初始化 query(1,l,r); printf("%d\n",maxh-minh); } return 0; }