洛谷 - Sound 静音问题

题目链接:https://www.luogu.com.cn/problem/P4392

思路:线段树,查询区间最大最小值的差是否在限制内

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int n,m,c;
int a[N];

struct SegmentTree{
    int l,r;
    int maxx,minn;//线段树记录区间最小最大值
}t[N*4];

//建树
void build(int p,int l,int r)
{
    t[p].l=l,t[p].r=r;
    if(l==r)
    {
        t[p].maxx=t[p].minn=a[l];
        return;
    }
    int mid=(l+r)/2;
    build(p*2,l,mid);
    build(p*2+1,mid+1,r);
    //传递最大最小值
    t[p].maxx=max(t[p*2].maxx,t[p*2+1].maxx);
    t[p].minn=min(t[p*2].minn,t[p*2+1].minn);
}

//查询区间最大值
int ask_maxx(int p,int l,int r)
{
    if(l<=t[p].l&&r>=t[p].r) return t[p].maxx;
    int mid=(t[p].l+t[p].r)/2;
    int val=-(1<<30);
    if(l<=mid) val=max(val,ask_maxx(p*2,l,r));
    if(r>mid) val=max(val,ask_maxx(p*2+1,l,r));
    return val;
}

int ask_minn(int p,int l,int r)
{
    if(l<=t[p].l&&r>=t[p].r) return t[p].minn;
    int mid=(t[p].l+t[p].r)/2;
    int val=(1<<30);
    if(l<=mid) val=min(val,ask_minn(p*2,l,r));
    if(r>mid) val=min(val,ask_minn(p*2+1,l,r));
    return val;
}

int main()
{
    cin>>n>>m>>c;
    for(int i=1;i<=n;i++) cin>>a[i];
    build(1,1,n);
    bool flag=false;
    for(int i=1;i+m-1<=n;i++)
    {
        int tmp=ask_maxx(1,i,i+m-1)-ask_minn(1,i,i+m-1);
        if(tmp<=c)//在给定范围内
        {
            cout<<i<<endl;
            flag=true;
        }
    }

    if(!flag) cout<<"NONE";
    return 0;
}

Bye~

posted @ 2021-09-23 14:58  AtomsH  阅读(40)  评论(0)    收藏  举报