您的位置:首页 > 其它

HDU 1754 I Hate It [线段树-单点更新]

2011-10-05 16:23 483 查看
题意:

分析:

/*
线段树一般也就两种写法:
1、传统递归建树的开2N-1即可。
2、按照堆结构非递归建树,要开2^([logN]+1),[]表示取上整。
至于为什么有一说要开4N,其实这也是上述第二种情况,因为2^([logN]+1)在最坏情况下接近4N。
比如N=1024时只用开2048,而N=1025时却需要开4096个节点,为3.99N。
但在大多数情况下远达不到4N,所以建议还是手动计算出使用大小。
*/


//AC CODE:

#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;

const int maxn = 222222;
int sum[maxn<<2];

void PushUP(int rt)
{
sum[rt] = max(sum[rt<<1],sum[rt<<1|1]);
}

void build(int l,int r,int rt)
{
if (l == r)
{
scanf("%d",&sum[rt]);
return ;
}
int m = (l + r) >> 1;
build(l , m , rt << 1);
build(m + 1 , r , rt << 1 | 1);
PushUP(rt);
}

void update(int p,int add,int l,int r,int rt)
{
if (l == r)
{
sum[rt] = add;
return ;
}
int m = (l + r) >> 1;
if (p <= m)
update(p , add , l , m , rt << 1);
else
update(p , add , m + 1 , r , rt << 1 | 1);
PushUP(rt);
}

int query(int L,int R,int l,int r,int rt)
{
if (L <= l && r <= R)
{
return sum[rt];
}
int m = (l + r) >> 1;
int ret = -1;
if (L <= m)
ret = max(ret,query(L , R , l , m , rt << 1));
if (R > m)
ret = max(ret,query(L , R , m + 1 , r , rt << 1 | 1));
return ret;
}

int main()
{
int n,m,a,b;
while(scanf("%d %d",&n,&m)!=EOF)
{
build(1 , n , 1);
char op[2];
while (m--)
{
scanf("%s %d %d",op,&a,&b);
if (op[0] == 'Q')
printf("%d\n",query(a , b , 1 , n , 1));
else
update(a , b , 1 , n , 1);
}
}
return 0;
}


用三目运算符?:代替了max就超时了,这里比较奇怪~

//TLE CODE:

#include <cstdio>

using namespace std;

const int maxn = 222222;
int sum[maxn<<2];

void PushUP(int rt)
{
sum[rt] = sum[rt<<1] > sum[rt<<1|1] ? sum[rt<<1] : sum[rt<<1|1];
}

void build(int l,int r,int rt)
{
if (l == r)
{
scanf("%d",&sum[rt]);
return ;
}
int m = (l + r) >> 1;
build(l , m , rt << 1);
build(m + 1 , r , rt << 1 | 1);
PushUP(rt);
}

void update(int p,int add,int l,int r,int rt)
{
if (l == r)
{
sum[rt] = add;
return ;
}
int m = (l + r) >> 1;
if (p <= m)
update(p , add , l , m , rt << 1);
else
update(p , add , m + 1 , r , rt << 1 | 1);
PushUP(rt);
}

int query(int L,int R,int l,int r,int rt)
{
if (L <= l && r <= R)
{
return sum[rt];
}
int m = (l + r) >> 1;
int ret = -1;
if (L <= m)
ret = ret>query(L , R , l , m , rt << 1)?ret:query(L , R , l , m , rt << 1);
if (R > m)
ret = ret>query(L , R , m + 1 , r , rt << 1 | 1)?ret:query(L , R , m + 1 , r , rt << 1 | 1);
return ret;
}

int main()
{
int n,m,a,b;
while(scanf("%d %d",&n,&m)!=EOF)
{
build(1 , n , 1);
char op[2];
while (m--)
{
scanf("%s %d %d",op,&a,&b);
if (op[0] == 'Q')
printf("%d\n",query(a , b , 1 , n , 1));
else
update(a , b , 1 , n , 1);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: