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


    P1198 [JSOI2008]最大数

    题目描述

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

    1、 查询操作。

    语法:Q L

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

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

    2、 插入操作。

    语法:A n

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

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

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

    输入格式

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

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

    输出格式

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

    输入输出样例

    输入 #1
    5 100
    A 96
    Q 1
    A 97
    Q 1
    Q 2
    
    输出 #1
    96
    93
    96
    

    说明/提示

    [JSOI2008]

    本题数据已加强

    题解:为线段树基础……适合刚学线段树的人写一下开拓一下思路。根据题目我们可以将线段的sum改为该线段中的最大值,这样会简单快速许多,具体见下代码;

    #define _CRT_SECURE_NO_DepRECATE
    #define _CRT_SECURE_NO_WARNINGS
    #include <cstdio>
    #include <iostream>
    #include <cmath>
    #include <iomanip>
    #include <string>
    #include <algorithm>
    #include <bitset>
    #include <cstdlib>
    #include <cctype>
    #include <iterator>
    #include <vector>
    #include <cstring>
    #include <cassert>
    #include <map>
    #include <queue>
    #include <set>
    #include <stack>
    #define ll long long
    #define INF 0x3f3f3f3f
    #define ld long double
    const ld pi = acos(-1.0L), eps = 1e-8;
    int qx[4] = { 0,0,1,-1 }, qy[4] = { 1,-1,0,0 }, qxx[2] = { 1,-1 }, qyy[2] = { 1,-1 };
    using namespace std;
    struct node
    {
        ll l = 0, r = 0, sum = 0, plz = 0, mlz = 1;
    }tree[1000000];
    ll  p = INF, maxx;
    inline void build(int i, int l, int r, int insert,int num)//树的编号 最左端 最右端 插入的值 插入的下标
    {
        tree[i].l = l;
        tree[i].r = r;
        if (l == r)//找到该点即替换为insert
        {
            tree[i].sum = insert;
        }
        else
        {
            if ((l + r) / 2 >= num)
            {
                build(i << 1, l, (l + r) / 2, insert, num);
            }
            else
            {
                build(i << 1 | 1, (l + r) / 2 + 1, r, insert, num);
            }
            tree[i].sum = max(tree[i << 1].sum, tree[i << 1 | 1].sum);//每个线段的sum为该线段的最大值
        }
    }
    inline ll search_max(int i, int l, int r)
    {
        if (tree[i].l >= l && tree[i].r <= r)//因sum即代表该线段的最大值,所以找到完全包含的线段就可以直接返回sum
        {
            return tree[i].sum;
        }
        if (tree[i].l > r || tree[i].r < l)
        {
            return 0;
        }
        ll ans = -INF;
        if (l <= tree[i << 1].r)
        {
            ans = max(ans, search_max(i << 1, l, r));
        }
        if (r >= tree[i << 1 | 1].l)
        {
            ans = max(ans, search_max(i << 1 | 1, l, r));
        }
        return ans;
    }
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        ll m, d, t = 0, sum = 1, b,input;
        char x;
        cin >> m >> d;
        for (int i = 0; i < m; i++)
        {
            cin >> x;
            if (x == 'A')
            {
                cin >> input;
                input = (input + t) % d;
                build(1, 1, m, input, sum);//因为最多只能插入m个,所以可以直接以m为r
                sum++;
            }
            else
            {
                cin >> b;
                t = search_max(1, sum - b, sum - 1);
                cout << t << endl;
            }
        }
        return 0;
    }
  • 相关阅读:
    【前端】用 npm 安装 yarn
    【前端】HTML复习巩固
    【前端】JS-删除绑定事件
    【前端】CSS3--动画animation的基本使用,3分钟快速实现一个小动画
    【GitHub】一文入门GitHub的使用,抓紧区交友吧!!
    【git】一文让你入门git的使用
    【前端】外边距合并问题 -- 嵌套盒子
    【前端】height 和 line-height的区别
    前端各种高度宽度视图
    关于 super() , 和 this , bind(this)的粗俗理解
  • 原文地址:https://www.cnblogs.com/Load-Star/p/12670810.html
Copyright © 2020-2023  润新知