线段树专题练习一hrbust oj1752 Page Rank

http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1752
这是题目链接,挺好的一道练习线段树的模板题,单点修改加上求区间最大值及其下标,其实这题在你理解了线段树后真的是非常简单(勿喷啊,我真的是菜,理解了好久终于懂了有点兴奋庆祝一下自己的学习成果),思路没啥说的大家估计都知道,就是讲解一下代码的含义吧,有助于像我一样的弱鸡理解线段树(大佬勿喷)。

#include <bits/stdc++.h>
typedef long long ll;
#define pb push_back
#define db double
#define lson l,m,rt*2
#define rson m+1,r,rt*2+1
using namespace std;
const int N = 111111;
int tree[N << 2];//保留的是最大值
int posn[N << 2];//保留下标
int pos;//保留最大值的下标
void pushup(int rt)
{
    if(tree[rt << 1] > tree[rt << 1|1])//求最大值,更新区间最大值
    {
        tree[rt] = tree[rt << 1];
        posn[rt] = posn[rt << 1];//下标随之更新
    }
    else
    {
        tree[rt] = tree[rt << 1 | 1];
        posn[rt] = posn[rt << 1 | 1];
    }
}
void build(int l,int r,int rt)
{
    if(l == r)
    {
        scanf("%d",&tree[rt]);
        posn[rt] = l;
    }
    else
    {
       int m = (l+r)>>1;
       build(lson);
       build(rson);
       pushup(rt);
    }
}
void update(int p,int c,int l,int r,int rt)
{
    if(l == r)
    {
        tree[rt] = c;
    }
    else
    {
        int m = (l+r)>>1;
        if(p <= m)
        {
            update(p,c,lson);
        }
        else
        {
            update(p,c,rson);
        }
        pushup(rt);
    }
}
int query(int L,int R,int l,int r,int rt)
{
    if(L <= l && r <= R)
    {
        pos = posn[rt];
        return tree[rt];
    }
    else
    {
        int m = (l + r) >> 1;
        int ret1 = INT_MIN;
        int ret2 = INT_MIN;
        if(L <= m)
        {
            ret1 = query(L,R,lson);
        }
        if(R > m)
        {
            ret2 = query(L,R,rson);
        }
        if(ret1 > ret2)
        {
            pos = posn[rt*2];
        }
        else//包含了等于时右儿子的下标一定比左二子大所以为了满足题意。
        {
            pos = posn[rt*2|1];
            ret1 = ret2;
        }
        return ret1;
    }
}
int main()
{
    int n,m;
    while(~scanf("%d",&n))
    {
        build(1,n,1);
        scanf("%d",&m);
        char op[2];
        int a,b;
        while(m--)
        {
            scanf("%s",op);//这里就是如果输入单个字符就会出现一些输入的问题,为了避免就直接来个长度为二的字符串。
            if(op[0] == 'Q')
            {
                printf("%d %d\n",pos,query(1,n,1,n,1));
            }
            else
            {
                scanf("%d%d",&a,&b);
                update(a,b,1,n,1);
            }
        }
        printf("\n");
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值