題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=1754
題目比較簡單裸線段樹,注意在查詢時根據已經查詢出來的結果進行最佳化
其實寫這個題目的目的是測試一下用數組下標寫的線段樹快,還是用指標
速度快,結果這個題目測試出來的結果一樣,都是500ms,不知道這個算
是沒測出結果還是說結果就是兩者速度差不多!
數組下標:
#include <iostream>#include <string.h>#include <stdio.h>#include <algorithm>using namespace std;#define maxn 300050#define Max(a,b) (a>b?a:b)struct node{ int MAX; int L,R; int left,right;}po[maxn*4];int pos;int ans;int n,m,score[maxn];int build_tree(int root){ if(po[root].L == po[root].R) { po[root].MAX=score[po[root].L]; return 0; } int mid=(po[root].L+po[root].R)>>1; po[root].left=pos; po[pos].L=po[root].L,po[pos].R=mid; pos++; build_tree(po[root].left); po[root].right=pos; po[pos].L=mid+1,po[pos].R=po[root].R; pos++; build_tree(po[root].right); po[root].MAX=Max(po[po[root].left].MAX,po[po[root].right].MAX); return 0;}int query(int root,int L,int R){ if(po[root].MAX < ans) return 0; if(po[root].L==L && po[root].R==R) { if(ans <po[root].MAX) ans=po[root].MAX; return 0; } int mid=(po[root].L + po[root].R)>>1; if(R<=mid) query(po[root].left,L,R); else if(L > mid) query(po[root].right,L,R); else query(po[root].left,L,mid),query(po[root].right,mid+1,R); return 0;}int update(int root,int a,int b){ if(po[root].L==po[root].R)//這裡不用判斷是否等於 a,肯定等於嘛 { po[root].MAX=b; return 0; } int mid=(po[root].L+po[root].R)>>1; if(a<=mid) update(po[root].left,a,b); else update(po[root].right,a,b); po[root].MAX=Max(po[po[root].left].MAX,po[po[root].right].MAX); return 0;}int main(){ int i,j,k; char ch; int a,b; while(scanf("%d%d",&n,&m)!=EOF) { po[0].MAX=0; po[0].L=1,po[0].R=n; pos=1; ans=0; for(i=1;i<=n;i++) scanf("%d",&score[i]); build_tree(0); for(i=0;i<m;i++) { getchar(); scanf("%c%d%d",&ch,&a,&b); if(ch=='Q') { query(0,a,b); printf("%d\n",ans); ans=0; } else { update(0,a,b); } } } return 0;}
指標
#include <iostream>#include <string.h>#include <stdio.h>#include <algorithm>using namespace std;#define maxn 300050#define Max(a,b) (a>b?a:b)struct node{ int MAX; int L,R; node *left,*right;}po[maxn*4];int pos;int ans;int n,m,score[maxn];int build_tree(node *root){ if(root->L == root->R) { root->MAX=score[root->L]; return 0; } int mid=(root->L+root->R)>>1; root->left=&po[pos]; po[pos].L=root->L,po[pos].R=mid; pos++; build_tree(root->left); root->right=&po[pos]; po[pos].L=mid+1,po[pos].R=root->R; pos++; build_tree(root->right); root->MAX=Max(root->left->MAX,root->right->MAX); return 0;}int query(node *root,int L,int R){ if(root->MAX < ans) return 0; if(root->L==L && root->R==R) { if(ans <root->MAX) ans=root->MAX; return 0; } int mid=(root->L + root->R)>>1; if(R<=mid) query(root->left,L,R); else if(L > mid) query(root->right,L,R); else query(root->left,L,mid),query(root->right,mid+1,R); return 0;}int update(node *root,int a,int b){ if(root->L==root->R)//這裡不用判斷是否等於 a,肯定等於嘛 { root->MAX=b; return 0; } int mid=(root->L+root->R)>>1; if(a<=mid) update(root->left,a,b); else update(root->right,a,b); root->MAX=Max(root->left->MAX,root->right->MAX); return 0;}int main(){ int i,j,k; char ch; int a,b; while(scanf("%d%d",&n,&m)!=EOF) { po[0].MAX=0; po[0].L=1,po[0].R=n; pos=1; ans=0; for(i=1;i<=n;i++) scanf("%d",&score[i]); build_tree(&po[0]); for(i=0;i<m;i++) { getchar(); scanf("%c%d%d",&ch,&a,&b); if(ch=='Q') { query(&po[0],a,b); printf("%d\n",ans); ans=0; } else { update(&po[0],a,b); } } } return 0;}