鏈接:https://ac.nowcoder.com/acm/contest/6874/I
來源:牛客網
題目描述
《無限的斯特拉托斯》又稱之為名作之壁,其銷量一直被圈內人士津津樂道。給你n個數字,第iii個數字a[i]表示名作之壁第i天的銷量。若某段區間[l,r]中最大值和最小值之差大於k,則稱該區間為暢銷區間。請問一共有多少個區間為暢銷區間?
輸入描述:
第一行兩個正整數n,k,其中n≤1e7,k≤1e9。
接下來一行三個正整數a[0],b,c,按照a[i]=(a[i−1]×b+c)%1e9的規則生成第1天到第nn天的銷量,a[0]不算入區間計算,其中a[0],b,c≤1e9。
輸出描述:
輸出暢銷區間的個數。
示例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; }