UOJ Logo SHYI的博客

博客

新博客 [JSOI2008]最大数maxnumber 题解

2016-07-21 19:19:51 By SHYI

题目大意:维护一个数列,有两种操作:1、 查询当前数列中末尾L个数中的最大的数,并输出这个数的值。限制:L不超过当前数列的长度。2、插入操作:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,再将所得答插入到数列的末尾。初始时数列是空的,没有一个数。

思路:讲道理这道题用线段树肯定不是最好的(比如用栈),但是我现在在学线段树,就拿来练练手。线段树裸题,有单点加入、区间查询操作。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

int da[800001];

void add(int l,int r,int x,int y,int cur)
{
    da[cur]=max(da[cur],y);
    if (l==r) return;
    int mid=l+r>>1;
    if (x>mid) add(mid+1,r,x,y,cur<<1|1);
    else add(l,mid,x,y,cur<<1);
}

int ask(int L,int R,int l,int r,int cur)
{
    if (L>=l && R<=r) return da[cur];
    int mid=L+R>>1,ans=0;
    if (l<=mid) ans=max(ans,ask(L,mid,l,r,cur<<1));
    if (r>mid) ans=max(ans,ask(mid+1,R,l,r,cur<<1|1));
    return ans;
}

int main()
{
    int m,mod,ans=0,n=0;
    scanf("%d%d",&m,&mod);
    for (int i=1;i<=m;i++)
    {
        int l;
        char ch=getchar();
        while (ch<'A' || ch>'Z') ch=getchar();
        scanf("%d",&l);
        if (ch=='A')
        {
            n++;
            int x=(l+ans)%mod;
            add(1,m,n,x,1);
        }
        else printf("%d\n",ans=ask(1,m,n-l+1,n,1));
    }
    return 0;
}

评论

暂无评论

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。