タイトル
質問の意味を簡素化:
長さ\(N- \)配列のための2つの位置の場合\(L、R&LT \)は、それらが間隔である\([L、R] \ ) で得られた最大値と二番目に大きい値、\(P_1 \ )拠出、その結果、最大であることが発生した場合\(P_2 \)貢献。
分析
これは、フォン・ホーエンハイムのことを思い出します。
長い顔の問題を見て、しかし、モデルのうち、質問の独自の意味を要約してみてください...
人々が直面しているこの問題は、実際にはそうではありませんので、私は見に行ってきましたyybの\(ブログ\を)これは質問の意味を理解し、。
私たちは、それだけで、次の作業を行うためには、このプロセスの出すことができ、これはこの区間の最大点間隔でなければならないことを、オーバーラップする2つの寄与ことがわかりました。
すなわち、プロセスの各点\(Iは\)最初の点の左側は、より大きい\(L [I] \)と、第1の点の右側がより大きい\(R&LT [I] \) 、これはすることができ以下のようなモノトーンのスタックで二回総なめにしました。
それから
- その後、間隔の\(Lは、[i]は\)する(R [i]が\)\た\(P_1 \)の寄与を、
- 左端点用(I-SIM \ L [I]を+1しました1 \)\、右端点\(R [I] \)間隔が有する\(P_2 \)の寄与を、
- 左の点のための\(L [I]が\) 、右端点\(I + 1 \ SIM R [I] -1 \) 間隔が存在する\(P_2 \)貢献。
だから、オフライン処理することができます。
それから
- 我々は、掃引\(R [I] \) 、更新点\(L [I] \)の寄与を、
- 我々は、掃引\(R [I] \) 、更新間隔\(L [i]を+1 \ SIM I-1 \) の寄与を、
- 我々は、掃引\([i]が\ Lの)、更新間隔\(I + 1 \ SIM R [I] -1 \) の寄与を。
これは、すべての貢献の範囲に対処します。
各インタロゲーションのために\([L、R&LT] \) 、上記3つの場合の全ては、2次元平面上のセグメントを抽象化1、その要求は、この範囲内の当量を要求し、走査線及び間隔は変更\(BITを\)この操作を完了すること。
コード
#include<bits/stdc++.h>
typedef long long ll;
const int maxn=2e5+10;
namespace IO
{
char buf[1<<15],*fs,*ft;
inline char getc() { return (ft==fs&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),ft==fs))?0:*fs++; }
template<typename T>inline void read(T &x)
{
x=0;
T f=1, ch=getchar();
while (!isdigit(ch) && ch^'-') ch=getchar();
if (ch=='-') f=-1, ch=getchar();
while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar();
x*=f;
}
char Out[1<<24],*fe=Out;
inline void flush() { fwrite(Out,1,fe-Out,stdout); fe=Out; }
template<typename T>inline void write(T x,char str)
{
if (!x) *fe++=48;
if (x<0) *fe++='-', x=-x;
T num=0, ch[20];
while (x) ch[++num]=x%10+48, x/=10;
while (num) *fe++=ch[num--];
*fe++=str;
}
}
using IO::read;
using IO::write;
int n,m,p1,p2;
namespace BIT
{
ll c1[maxn],c2[maxn];
inline int lowbit(int x) { return x & -x; }
inline void add(int x,int v) { for (int i=x; i<=n; i+=lowbit(i)) c1[i]+=v, c2[i]+=x*v; }
inline ll ask(int x) { ll ans=0; for (int i=x; i; i-=lowbit(i)) ans+=(x+1)*c1[i]-c2[i]; return ans; }
inline ll hsh(int l,int r) { return ask(r)-ask(l-1); }
}
using BIT::add;
using BIT::hsh;
struct QwQ{int x,l,r,v,id;}q[maxn<<2];
int cnt;
inline bool cmp1(QwQ a,QwQ b) { return a.x<b.x; }
struct Orz{int x,l,r,v;}o[maxn<<2];
int tot;
inline bool cmp2(Orz a,Orz b) { return a.x<b.x; }
ll ans[maxn]; int L[maxn],R[maxn];
int k[maxn],Stack[maxn],top;
int main()
{
read(n);read(m);read(p1);read(p2);
for (int i=1; i<=n; ++i) read(k[i]);
Stack[top=1]=0;
for (int i=1; i<=n; ++i)
{
while (top>1 && k[Stack[top]]<k[i]) --top;
L[i]=Stack[top], Stack[++top]=i;
}
Stack[top=1]=n+1;
for (int i=n; i>=1; --i)
{
while (top>1 && k[Stack[top]]<k[i]) --top;
R[i]=Stack[top], Stack[++top]=i;
}
for (int i=1,l,r; i<=m; ++i)
{
read(l);read(r);
ans[i]=(r-l)*p1;
q[++cnt]=(QwQ){r,l,r,1,i};
q[++cnt]=(QwQ){l-1,l,r,-1,i};
}
std::sort(q+1,q+cnt+1,cmp1);
for (int i=1; i<=n; ++i)
{
if (L[i] && R[i]<n+1) o[++tot]=(Orz){R[i],L[i],L[i],p1};
if (L[i] && R[i]>i+1) o[++tot]=(Orz){L[i],i+1,R[i]-1,p2};
if (L[i]+1<i && R[i]<n+1) o[++tot]=(Orz){R[i],L[i]+1,i-1,p2};
}
std::sort(o+1,o+tot+1,cmp2);
for (int i=1, j=1; i<=cnt; ++i)
{
while (j<=tot && o[j].x<=q[i].x) add(o[j].l,o[j].v), add(o[j].r+1,-o[j].v), ++j;
ans[q[i].id]+=q[i].v*hsh(q[i].l,q[i].r);
}
for (int i=1; i<=m; ++i) write(ans[i],'\n');
IO::flush();
return 0;
}