ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

AcWing 1275. 最大数

2022-04-16 11:34:48  阅读:185  来源: 互联网

标签:last 最大数 int 1275 查询 添加 区间 AcWing op


题目传送门

题意:
给两种操作。
添加操作:向序列后添加一个数,序列长度变成 \(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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有