1)线段树求某区间最大值,用到线段树的建立、单点更新、区间最值查询。第三道线段树入门题目,敲起来还是很不熟练。另外,scanf读入string很麻烦;用cin读取string方便一些;如果追求再稍微快的那么一点,用scanf读取char,但要注意是否需要在每次scanf读取之前,先getchar()看看有没有必要吃掉回车(windows下)。
#include <iostream> #include <stdio.h> #include <string> using namespace std; const int maxm=200010*4; int a[maxm]; struct Node{ int left,right,best; }node[maxm]; void Build(int id,int l,int r){ node[id].left=l; node[id].right=r; if(l==r){ node[id].best=a[l]; return; } int mid=(l+r)>>1; Build(id<<1,l,mid); Build((id<<1)+1,mid+1,r); node[id].best=max(node[id<<1].best,node[(id<<1)+1].best); return; } void Update(int id,int i,int j){ if(node[id].left==i&&node[id].right==i){ node[id].best=j; return; } int mid=(node[id].left+node[id].right)>>1; if(i<=mid){ Update(id<<1,i,j); } else if(i>=mid+1){ Update((id<<1)+1,i,j); } node[id].best=max(node[id<<1].best,node[(id<<1)+1].best); return ; } int Query(int id,int i,int j){ if(node[id].left==i&&node[id].right==j){ return node[id].best; } int mid=(node[id].left+node[id].right)>>1; if(j<=mid){ return Query(id<<1,i,j); } else if(mid+1<=i){ return Query((id<<1)+1,i,j); } else{ return max(Query(id<<1,i,mid),Query((id<<1)+1,mid+1,j)); } } int main() { int n,m; while(~scanf("%d%d",&n,&m)){ for(int i=1;i<=n;i++){ scanf("%d",&a[i]); } Build(1,1,n); char com; int i,j; for(int k=1;k<=m;k++){ //cin>>com;//!!!!!!!!! //scanf("%s",&com[0]); getchar(); scanf("%c",&com); if(com=='Q'){ scanf("%d%d",&i,&j); cout<<Query(1,i,j)<<endl; } else if(com=='U'){ scanf("%d%d",&i,&j); Update(1,i,j); } } } return 0; }
2)
Description
Input
Output
Sample Input
5 6 1 2 3 4 5 Q 1 5 U 3 6 Q 3 4 Q 4 5 U 2 9 Q 1 5
Sample Output
5 6 5 9
Hint
Huge input,the C function scanf() will work better than cin