【洛谷P1198】最大数

这个题最大的难点在于插入,实际上我们可以假设这是一棵早就建好的线段树,插入只是单点赋值而已

#include<iostream>
#include<cstring>
#include<cstdio>
#include<queue>
using namespace std;
typedef long long lo;
lo m,d,t,tail,x;
char s;
struct in
{
    lo l,r,mx;
}ter[800080];
inline void build(lo l,lo r,lo w)//我们可以把它看做这是一棵有m个点的线段树,那么只要支持单点修改和区间查询即可 
{
    ter[w].l=l,ter[w].r=r,ter[w].mx=0;
    if(l==r)
        return;
    lo mid=l+r>>1;
    build(l,mid,w<<1),build(mid+1,r,w<<1|1);
}
inline void up(lo w)
{
    ter[w].mx=max(ter[w<<1].mx,ter[w<<1|1].mx);
}
void add(lo l,lo z,lo n,lo w)
{
    if(ter[w].l==ter[w].r&&ter[w].l==l)
    {
        ter[w].mx=(z+n)%d;return;//单点赋值 
    }
    lo mid=ter[w].l+ter[w].r>>1;
    if(l<=mid)
        add(l,z,n,w<<1);
    else
        add(l,z,n,w<<1|1);
    up(w);
}
lo ask(lo l,lo r,lo w)
{
    if(ter[w].l==l&&ter[w].r==r)
        return ter[w].mx;
    lo mid=ter[w].l+ter[w].r>>1;
    if(r<=mid)
        return ask(l,r,w<<1);
    else if(l>mid)
        return ask(l,r,w<<1|1);
    else
        return max(ask(l,mid,w<<1),ask(mid+1,r,w<<1|1));
}
int main()
{
    scanf("%lld%lld",&m,&d);
    build(1,m,1);
    for(int i=1;i<=m;i++)
    {
        cin>>s>>x;
        if(s=='A')
            add(++tail,t,x,1); 
        else
        {
            t=ask(tail-x+1,tail,1);printf("%lld\n",t);
        }//需要记录下有用的区间右端点和上次所查询的答案 
    }
}

 

posted @ 2017-10-28 11:21  那一抹落日的橙  阅读(309)  评论(0编辑  收藏  举报