2021-2022-1 ACM集训队每月程序设计竞赛F: max or min

Posted ZZXzzx0_0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021-2022-1 ACM集训队每月程序设计竞赛F: max or min相关的知识,希望对你有一定的参考价值。

F: max or min

题意
给 你 一 个 n 个 数 的 数 组 和 一 个 k 给你一个n个数的数组和一个k nk
1 < = n , k < = 1 e 5 , 1 <= n , k <= 1e5 , 1<=n,k<=1e5,
a 1 , a 2 , . . . . . . a n a1,a2,......an a1,a2,......an
1 < = a i < = n 1 <= ai <= n 1<=ai<=n
求 一 个 最 长 区 间 [ l , r ] 求一个最长区间[l,r] [l,r]
满 足 这 个 区 间 的 最 大 值 − 最 小 值 < = k 满足这个区间的最大值-最小值<=k <=k
思路
假 设 当 前 区 间 为 m i d 假设当前区间为mid mid
如 果 存 在 长 度 为 m i d 的 区 间 满 足 最 大 值 − 最 小 值 < = k 如果存在长度为mid的区间满足最大值-最小值<=k mid<=k
说 明 m i d 可 以 变 大 说明mid可以变大 mid
否 则 m i d 变 小 否则mid变小 mid

因 此 考 虑 二 分 查 找 m i d 因此考虑二分查找mid mid
时 间 复 杂 度 l o g n 时间复杂度logn logn

查 询 区 间 最 大 值 和 最 小 值 可 以 考 虑 查询区间最大值和最小值可以考虑
树 状 数 组 / s t 表 / 线 段 树 树状数组/st表/线段树 /st/线

线 段 树 查 询 n l o g n 总 时 间 复 杂 度 n l o g n l o g n 线段树查询nlogn总时间复杂度nlognlogn 线nlognnlognlogn
s t 表 查 询 o 1 总 时 间 复 杂 度 n l o g n st表查询o1总时间复杂度nlogn sto1nlogn
树 状 数 组 与 线 段 树 类 似 树状数组与线段树类似 线

其 实 还 有 个 很 妙 的 做 法 其实还有个很妙的做法
s e t + 双 指 针 动 态 维 护 n l o g n set+双指针动态维护 nlogn set+nlogn
每 次 假 设 i 这 个 下 标 为 区 间 右 端 点 每次假设i这个下标为区间右端点 i
找 到 最 大 的 一 个 左 端 点 找到最大的一个左端点
同 时 更 新 答 案 同时更新答案
方 法 一 方法一
时间复杂度 线 段 树 + 二 分 O n l o g l o g n 线段树+二分Onloglogn 线+Onloglogn

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int N = 200010;

int n , m , k ;
struct Node

    int l, r;
    int v , minv ;  // 区间[l, r]中的最大值和最小值
tr[N * 4];
int a[N];

void pushup(int u)  // 由子节点的信息,来计算父节点的信息

    tr[u].v = max(tr[u<<1].v,tr[u<<1|1].v);
    tr[u].minv = min(tr[u<<1].minv,tr[u<<1|1].minv);


void build(int u, int l, int r)

    if(l == r) tr[u] = l,r,a[r],a[r];
    else
    
        tr[u] = l, r;
        int mid = r + l >> 1 ;
        build(u << 1 , l , mid ) , build(u << 1 | 1 , mid + 1 , r);
        pushup(u);
    


int query(int u, int l, int r)

    if(tr[u].l >= l && tr[u].r <= r) return tr[u].v ;

    int v = -1e9 ;
    int mid = tr[u].l + tr[u].r >> 1 ;
    if(l <= mid) v = max(v,query(u << 1 , l ,r));
    if(r > mid) v = max(v,query(u << 1 | 1 , l , r));

    return v ;


int query1(int u, int l, int r)

    if(tr[u].l >= l && tr[u].r <= r) return tr[u].minv ;

    int v = 1e9 ;
    int mid = tr[u].l + tr[u].r >> 1 ;
    if(l <= mid) v = min(v,query1(u << 1 , l ,r));
    if(r > mid) v = min(v,query1(u << 1 | 1 , l , r));

    return v ;


bool check(int mid)

    int x = mid ;
    for(int i = 1 ; i + x - 1 <= n ; i ++)
    
        if(query(1,i,i+x-1) - query1(1,i,i+x-1) <= k) return true ;
    
    return false ;


int main()

    cin >> n >> k ;
    for(int i = 1 ; i <= n ; i ++) scanf("%d",&a[i]);
    build(1,1,n);
    int l = 1 , r = n ;
    while(l < r)
    
        int mid = r + l + 1 >> 1 ;
        if(check(mid)) l = mid ;
        else r = mid - 1 ;
    
    cout << l << "\\n" ;
    
    return 0;

方 法 二 方法二
时间复杂度 s e t + 双 指 针 O n l o g n set+双指针Onlogn set+Onlogn

#include <bits/stdc++.h>
#define sz(x) ((int)(x).size())
using namespace std;
const int N = 1e6 + 10 ;

int n , k ;
int a[N] ;

signed main()

    cin >> n >> k ;
    for(int i = 1 ; i <= n ; i ++) scanf("%d",a + i) ;
    
    int res = 0 ;
    multiset<int> q ;
    for(int i = 1 , j = 1 ; i <= n ; i ++)
    
        q.insert(a[i]) ;
        while(q.size() && *--q.end() - *q.begin() > k && j <= n) 
        
            q.erase(q.find(a[j ++])) ;
        
        res = max(res,sz(q)) ;
    
    cout << res << "\\n" ;
    
    return 0;

方 法 三 方法三
时间复杂度 s t 表 + 二 分 O n l o g n st表+二分Onlogn st+Onlogn

#include<bits/stdc++.h>
using namespace std;
int a[100005],maxn[100005][30],minn[100005][30];
int n,k;
void st_prework()
	for(int i=1;i<=n;i++)maxn[i][0]=minn[i][0]=a[i];
	int t=log(n)/log(2)+1;
	for(int j=1;j<t;j++)
		for(int i=1;以上是关于2021-2022-1 ACM集训队每月程序设计竞赛F: max or min的主要内容,如果未能解决你的问题,请参考以下文章

BUCT - 2021-2022-1 ACM集训队每周程序设计竞赛(10)题解

BUCT - 2021-2022-1 ACM集训队每周程序设计竞赛(10)题解

BUCT - 2021-2022-1 ACM集训队每周程序设计竞赛(10)题解

BUCT - 2021-2022-1 ACM集训队每周程序设计竞赛题解

BUCT - 2021-2022-1 ACM集训队每周程序设计竞赛题解

BUCT - 2021-2022-1 ACM集训队每周程序设计竞赛题解