區間最大值-最小值的區間的個數


鏈接:https://ac.nowcoder.com/acm/contest/6874/I
來源:牛客網

題目描述

《無限的斯特拉托斯》又稱之為名作之壁,其銷量一直被圈內人士津津樂道。給你n個數字,第iii個數字a[i]表示名作之壁第i天的銷量。若某段區間[l,r]中最大值和最小值之差大於k,則稱該區間為暢銷區間。請問一共有多少個區間為暢銷區間?

輸入描述:

第一行兩個正整數n,k,其中n≤1e7k≤1e9

接下來一行三個正整數a[0],b,c,按照a[i]=(a[i−1]×b+c)%1e9的規則生成第1天到第nn天的銷量,a[0]不算入區間計算,其中a[0],b,c≤1e9

輸出描述:

輸出暢銷區間的個數。

示例1

輸入

復制
4 1
1 1 1

輸出

復制
3




這個題目的意思就是所找有多少個區間內的最大值-最小值>k的區間個數
對於維護區間內的最值那肯定是單調隊列了

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
// 之差至少2 
inline int read()
{
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
const int maxn=1e7+100;
const int mod=1e9;
ll a[maxn];
ll qmax[maxn];
ll qmin[maxn];
int main(){
    int n;
    ll b,c,k;
    cin>>n>>k;
    cin>>a[0]>>b>>c;
    for(int i=1;i<=n;i++){
        a[i]=(1ll*a[i-1]*b+c)%mod;
    }
    ll ans=0,l=1,h1=1,t1=0,h2=1,t2=0;
    for(int i=1;i<=n;i++){
        while(h1<=t1&&a[i]>=a[qmax[t1]]) t1--;
        while(h2<=t2&&a[i]<=a[qmin[t2]]) t2--;
        qmax[++t1]=i;
        qmin[++t2]=i;
        while(h1<=t1&&h2<=t2&&a[qmax[h1]]-a[qmin[h2]]>k){
            ans+=n-i+1;//計算權值 
            l++;
            if(qmax[h1]<l) h1++;
            if(qmin[h2]<l) h2++;
        }
    } 
    cout<<ans<<endl;
} 
 
             

 




免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM