P1198 [JSOI2008]最大數(線段樹基礎)

P1198 [JSOI2008]最大數

題目描述

如今請求你維護一個數列,要求提供如下兩種操做:html

一、 查詢操做。node

語法:Q Lios

功能:查詢當前數列中末尾L個數中的最大的數,並輸出這個數的值。ui

限制:LL不超過當前數列的長度。(L > 0)(L>0)spa

二、 插入操做。code

語法:A norm

功能:將nn加上tt,其中tt是最近一次查詢操做的答案(若是還未執行過查詢操做,則t=0t=0),並將所得結果對一個固定的常數DD取模,將所得答案插入到數列的末尾。htm

限制:nn是整數(可能爲負數)而且在長整範圍內。blog

注意:初始時數列是空的,沒有一個數。ip

輸入格式

第一行兩個整數,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;
}
相關文章
相關標籤/搜索