题目链接: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;
}