• [JSOI2008]最大数(线段树基础)


    题目描述

    现在请求你维护一个数列,要求提供以下两种操作:

    1、 查询操作。

    语法:Q L

    功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值。

    限制: L 不超过当前数列的长度。(L > 0)

    2、 插入操作。

    语法:A n

    功能:将 n 加上 t ,其中 t 是最近一次查询操作的答案(如果还未执行过查询操作,则 t=0 ),并将所得结果对一个固定的常数 取模,将所得答案插入到数列的末尾。

    限制: n 是整数(可能为负数)并且在长整范围内。

    注意:初始时数列是空的,没有一个数。

    输入输出格式

    输入格式:

    第一行两个整数, MD ,其中 M 表示操作的个数 (M≤200,000)D 如上文中所述,满足 (0<D<2,000,000,000)

    接下来的 M 行,每行一个字符串,描述一个具体的操作。语法如上文所述。

    输出格式:

    对于每一个查询操作,你应该按照顺序依次输出结果,每个结果占一行。

    思路:

    从这道题的数据范围来看,他只有200000次操作

    从最坏情况来看,数列长最多只可能200000

    所以,这道题就变成了一道简单的线段树

    我们默认这是一棵已经开好的大小为200000的线段树

    A操作就是单点修改

    Q操作就是区间查询

    每个节点维护的是当前节点及其子树的最大值

    A操作就是一个简单的单点修改,只要记录上一次修改的位置,+1就是要修改的位置

    Q操作就是一个区间查询,查询该区间的最大值,只要改变return的东西就好了

    代码:

    // luogu-judger-enable-o2
    #include<iostream>
    #include<cstdio>
    #define rii register int i
    using namespace std;
    struct node{
        long long maxn;
    }x[800005];
    char cz;
    long long v,ans,m,d,mw;
    long long add(int wz,long long val,int l,int r,int bh)
    {
        if(l==r)
        {
            x[bh].maxn+=val;
            return x[bh].maxn;
        }
        int harf=(l+r)/2;
        if(wz>harf)
        {
            x[bh].maxn=max(x[bh].maxn,add(wz,val,harf+1,r,bh*2+1));
        }
        else
        {
            x[bh].maxn=max(x[bh].maxn,add(wz,val,l,harf,bh*2));
        }
        return x[bh].maxn;
    }
    long long ask(int l,int r,int nl,int nr,int bh)
    {
        long long ltt=0;
        if(l==nl&&r==nr)
        {
            return x[bh].maxn;
        }
        int half=(nl+nr)/2;
        if(l<=half&&r>half)
        {
            ltt=max(ltt,ask(l,half,nl,half,bh*2));
            ltt=max(ltt,ask(half+1,r,half+1,nr,bh*2+1));
        }
        else
        {
            if(l<=half)
            {
                ltt=max(ltt,ask(l,r,nl,half,bh*2));
            }
            else
            {
                ltt=max(ltt,ask(l,r,half+1,nr,bh*2+1));
            }
        }
        return ltt;
    }
    int main()
    {
        scanf("%lld%lld
    ",&m,&d);
        for(rii=1;i<=m;i++)
        {
            scanf("%c%lld
    ",&cz,&v);
            if(cz=='Q')
            {
                ans=ask(mw-v+1,mw,1,200000,1);
                printf("%d
    ",ans);
            }
            else
            {
                mw++;
    //            ans=1e9+7;
    //            r1=max(r1,v);
                add(mw,(ans+v)%d,1,200000,1);
    //            cout<<x[1].maxn;
            }
        }
    }
  • 相关阅读:
    CQUOJ 10819 MUH and House of Cards
    CQUOJ 9920 Ladder
    CQUOJ 9906 Little Girl and Maximum XOR
    CQUOJ 10672 Kolya and Tandem Repeat
    CQUOJ 9711 Primes on Interval
    指针试水
    Another test
    Test
    二分图匹配的重要概念以及匈牙利算法
    二分图最大匹配
  • 原文地址:https://www.cnblogs.com/ztz11/p/9296499.html
Copyright © 2020-2023  润新知