IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> CodeForces 1436 E. Complicated Computations(权值线段树) -> 正文阅读

[C++知识库]CodeForces 1436 E. Complicated Computations(权值线段树)

传送门

题意:

求所有子数组的 M E X MEX MEX?组成的序列的 M E X MEX MEX

题解:

首先,如果要使 M E X MEX MEX? 为 x x x ,则必须满足:

1. 1. 1. ( 1 , x ? 1 ) (1,x-1) (1,x?1) 都出现过

2. 2. 2. x x x 没出现过

那么怎么求出这些 x x x 呢,考虑暴力一点的做法,枚举右端点 i i i ,考虑是否存在区间使得 M E X MEX MEX x x x ,那么利用权值线段树维护每个值的最近出现的位置,求出 ( 1 , x ? 1 ) (1,x-1) (1,x?1)的最小的位置 p p p,如果最后一次出现 x x x 的位置在 p p p 之前,那么说明可以得到 x x x 。但是这样枚举肯定会 t l e tle tle? 。再观察,下一个 x x x 出现的位置肯定在 i i i 之后。那么我们对 x x x 枚举下一个出现的位置,然后考虑上一个出现的位置是否小于 p p p 。通俗的讲,就是枚举数组的每个位置,看上一个 a [ i ] a[i] a[i]出现的位置是否在 p p p 之前即可。

代码:

#pragma GCC diagnostic error "-std=c++11"
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
const int mod = 1e9 + 7;
const int MAXN = 2e5 + 5;
const int inf = 0x3f3f3f3f;
int a[MAXN];
int vis[MAXN], pre[MAXN];
struct node {
    int l, r;
    int mi;
    /* data */
} node[MAXN << 2];
void build(int l, int r, int num)
{
    node[num].l = l;
    node[num].r = r;
    if (l == r) {
        node[num].mi = 0;
        return;
    }
    int mid = (l + r) >> 1;
    build(l, mid, num << 1);
    build(mid + 1, r, num << 1 | 1);
    node[num].mi = min(node[num << 1].mi, node[num << 1 | 1].mi);
}
void updata(int pos, int val, int num)
{
    if (node[num].l == node[num].r) {
        node[num].mi = val;
        return;
    }
    int mid = (node[num].l + node[num].r) >> 1;
    if (pos <= mid)
        updata(pos, val, num << 1);
    else
        updata(pos, val, num << 1 | 1);
    node[num].mi = min(node[num << 1].mi, node[num << 1 | 1].mi);
}
int query(int l, int r, int num)
{
    if (node[num].l >= l && node[num].r <= r) {
        return node[num].mi;
    }
    int mid = (node[num].l + node[num].r) >> 1;
    int mi = 1e9;
    if (l <= mid)
        mi = min(mi, query(l, r, num << 1));
    if (r > mid)
        mi = min(mi, query(l, r, num << 1 | 1));
    return mi;
}
int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    for (int i = 1; i <= n + 2; i++)
        pre[i] = 0;
    build(1, n + 2, 1);
    for (int i = 1; i <= n; i++) {
        if (a[i] > 1) {
            vis[1] = 1;
            int pos = query(1, a[i] - 1, 1);
            if (pos>pre[a[i]]){
                vis[a[i]] = 1;
            }
        }
        updata(a[i], i, 1);
        pre[a[i]] = i;
    }
    for (int i = 2; i <= n + 2; i++){
        if(query(1,i-1,1)>pre[i]){
            vis[i] = 1;
        }
    }
    for (int i = 1; i <= n + 2;i++){
        if(!vis[i]){
            cout << i << endl;
            return 0;
        }
    }
}
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-09-13 09:05:31  更:2021-09-13 09:05:40 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:54:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码