其他分享
首页 > 其他分享> > AcWing 1275. 最大数

AcWing 1275. 最大数

作者:互联网

题目传送门

题意:
给两种操作。
添加操作:向序列后添加一个数,序列长度变成 \(n+1\);
询问操作:询问这个序列中最后 \(L\) 个数中最大的数是多少。
思路:线段树裸题,通过单点修改和回溯中的\(pushup\)维护区间最大值。

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int N = 200010;
int m; // m个操作
int p; //需要结果mod p

//线段树的结构体
struct Node {
    int l, r;
    int v;    // 区间[l, r]中的最大值
} tr[N << 2]; //开4倍空间

void pushup(int u) { // 由子节点的信息,来计算父节点的信息
    tr[u].v = max(tr[u << 1].v, tr[u << 1 | 1].v);
}

//构建
void build(int u, int l, int r) {
    tr[u] = {l, r};     //记录区间起始值,不要忘记yxc两次倒在这里的历史~
    if (l == r) return; //递归出口,only one就需要返回了
    int mid = l + r >> 1;
    build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
}

//查询以u为根节点,区间[l, r]中的最大值
int query(int u, int l, int r) {
    if (tr[u].l >= l && tr[u].r <= r) return tr[u].v; //包含左儿子与右儿子,那么直接返回我的结果
    int mid = tr[u].l + tr[u].r >> 1;
    int v = 0;
    if (l <= mid) v = query(u << 1, l, r);            //与左儿子有交,递归求解
    if (r > mid) v = max(v, query(u << 1 | 1, l, r)); //与右儿子有交,再次递归
    return v;
}

// u为结点编号,更新该结点的区间最大值
void modify(int u, int x, int v) {
    if (tr[u].l == tr[u].r)
        tr[u].v = v; //叶节点,递归出口
    else {
        int mid = tr[u].l + tr[u].r >> 1;
        //分治处理左右子树, 寻找x所在的子树
        if (x <= mid)
            modify(u << 1, x, v);
        else
            modify(u << 1 | 1, x, v);
        //回溯,拿子结点的信息更新父节点, 即pushup操作
        tr[u].v = max(tr[u << 1].v, tr[u << 1 | 1].v);
    }
}
// n表示树中的结点个数, last保存上一次查询的结果
int n, last;
int main() {
    cin >> m >> p;
    //每次向序列后添加一个数,连添加带查询,共有m次操作,所以结点的区间最大不超过m
    //初始化线段树, 结点的区间最多为[1, m]。
    build(1, 1, m); //其实构建本质上就是:(1)标识有多少个点,(2)每个点描述的是哪个区间

    int x;
    char op;
    while (m--) {
        cin >> op >> x;
        if (op == 'A') {
            //对于n+1的位置进行修改,值=(最后一次的last查询值 + x )%p
            modify(1, n + 1, ((LL)last + x) % p);
            n++;
        } else {
            //查询[n - x + 1, n]内的最大值,u = 1:从根节点开始查询
            last = query(1, n - x + 1, n);
            printf("%d\n", last);
        }
    }
    return 0;
}

标签:last,最大数,int,1275,查询,添加,区间,AcWing,op
来源: https://www.cnblogs.com/littlehb/p/16152232.html