今天还是简单的回顾了一下线段树,加深影响,这题也是入门题,果然不是很输,一开始直接用链表,发现MLE。于是换了数组,发现数组很容易写,并且思路也很清晰。
今天的复习总结:
1、线段树用数组做会更好,代码明显好看很多!网上也有一个大牛写的很好的代码,值得借鉴!
2、线段树要和其他知识点连接的话,会比较难以想到用线段树,所以我要加深对线段树目的,效率,和结果都有更深的理解!
3、听说splay可以加深理解!
#include <iostream>
#include <stdio.h>
using namespace std;
#define MAXL 200010
struct Node
{
int l,r,val;
}node[MAXL*4];
int loc[MAXL];
void Build(int l,int r,int len)
{
if(l == r) {loc[l] = len;node[len].l = l;node[len].r = r;node[len].val = 0;return;}
node[len].l = l;node[len].r = r;node[len].val = 0;
Build(l,(l+r)/2,2*len);
Build((l+r)/2+1,r,2*len+1);
}
void Update(int pos,int num)
{
node[loc[pos]].val = num;
int p = loc[pos];
while(p != 1)
{
//cout<<pos<<endl;
p/=2;
node[p].val = max(node[2*p].val,node[2*p+1].val);
}
}
int Query(int l,int r,int len)
{
//cout<<l<<" "<<r<<" "<<len<<" "<<node[len].l<<" "<<node[len].r<<endl;
if(l == node[len].l &&r == node[len].r) return node[len].val;
int sum = 0;
if(l <= (node[len].l+node[len].r)/2) sum = max(Query(l,min((node[len].l+node[len].r)/2,r),2*len),sum);
if(r>(node[len].l+node[len].r)/2) sum = max(Query(max((node[len].l+node[len].r)/2+1,l),r,2*len+1),sum);
return sum;
}
int main()
{
int T,O;
while(scanf("%d%d",&T,&O)!=EOF)
{
Build(0,T-1,1);
//for(int i = 0;i < 9;i ++) cout<<node[i].l<<" "<<node[i].r<<endl;
for(int i = 0;i < T;i ++)
{
int p;
scanf("%d",&p);
Update(i,p);
}
char s[2];
while(O --)
{
scanf("%s",&s);
if(s[0] == 'U')
{
int p,num;scanf("%d%d",&p,&num);
Update(p-1,num);
}
else
{
int p,num;scanf("%d%d",&p,&num);
printf("%d\n",Query(p-1,num-1,1));
}
}
}
}