线段树——BZOJ1012/Luogu1198 [JSOI2008]最大数

http://www.lydsy.com/JudgeOnline/problem.php?id=1012
https://www.luogu.org/problem/show?pid=1198
经典老题现在才AC。。。
这题方法很多,有单调栈,有线段树,有树状数组……
我是用线段树写的
其实就是胜者树求区间最大
我们建一棵大小为m的线段树,每个节点赋值为-2^30,然后插入节点(其实就是修改)和询问都是模板了

#include<bits/stdc++.h>
#define ll long long
using namespace std;
char c[5];
ll m,d,q=0,n=0;
ll t[800001]={0},lt[800001],rt[800001];
inline void build(ll l,ll r,ll nod){
    t[nod]=-1<<30;lt[nod]=l;rt[nod]=r;
    if(l==r)return;
    ll mid=(l+r)>>1;
    build(l,mid,nod*2);
    build(mid+1,r,nod*2+1);
}
inline void xg(int i,int p,int nod){
    if(lt[nod]==i&&rt[nod]==i)t[nod]=p;
    else{
        ll mid=(lt[nod]+rt[nod])>>1;
        if(i>mid)xg(i,p,nod*2+1);
        else xg(i,p,nod*2);
        t[nod]=max(t[nod*2],t[nod*2+1]);
    }
}
inline ll s(int i,int j,int nod){
    if(lt[nod]==i&&rt[nod]==j)return t[nod];
    ll mid=(lt[nod]+rt[nod])>>1;
    if(j<=mid)return s(i,j,nod*2);
    if(i>=mid+1)return s(i,j,nod*2+1);
    ll le=s(i,mid,nod*2),re=s(mid+1,j,nod*2+1);
    return max(le,re);
}
int main()
{
    scanf("%lld%lld",&m,&d);
    build(1,m,1);   
    ll x;
    for(int i=1;i<=m;i++){
        scanf("%s",c);
        scanf("%lld",&x);
        if(c[0]=='A'){
            n++;xg(n,(x+q)%d,1);
        }else{
            q=s(n-x+1,n,1);
            printf("%lld\n",q);
        }
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值