P3246 [HNOI2016] 序列 题解
P3246 [HNOI2016] 序列
直到最后一步都是容易想到的,而最后一步恰是本题的关键所在。
首先看到 ST 表和莫队是容易想到的,那么有了莫队就应该考虑如何扩展区间。我们尝试把
单调栈应该就有了。
但每次扩展的时候都跑一遍单调栈显然不现实,那么我们先预处理
下面是核心内容。考虑设一个
于是这题就做完了。
using ll=long long;
constexpr int MAXN=1e5+5;
int n,Q,t,F,logn[MAXN],f[MAXN][21];
int lf[MAXN],rf[MAXN],stk[MAXN],top;
ll a[MAXN],sml[MAXN],smr[MAXN],ans[MAXN];
struct Ask{
int l,r,id;
bool operator<(const Ask&x)const{
return l/t!=x.l/t?l<x.l:l/t&1?r<x.r:r>x.r;
}
}q[MAXN];
void ST(){
for(int j=1;j<=F;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
f[i][j]=Min(f[i][j-1],f[i+(1<<(j-1))][j-1]);
}
int amn(int l,int r){
int s=logn[r-l+1];
return Min(f[l][s],f[r-(1<<s)+1][s]);
}
ll gtl(int l,int r){
int mn=amn(l,r);
return a[mn]*(r+1-mn)+smr[l]-smr[mn];
}
ll gtr(int l,int r){
int mn=amn(l,r);
return a[mn]*(mn-l+1)+sml[r]-sml[mn];
}
int main(){
n=read(),Q=read();
F=__lg(n),t=sqrt(n);
a[0]=a[n+1]=-2e9,logn[0]=-1;
for(int i=1;i<=n;i++){
a[i]=read();
logn[i]=logn[i>>1]+1;
f[i][0]=i;
while(top&&a[stk[top]]>=a[i]) top--;
lf[i]=stk[top];
sml[i]=sml[lf[i]]+a[i]*(i-lf[i]);
stk[++top]=i;
}
stk[top=1]=n+1;
for(int i=n;i;i--){
while(top&&a[stk[top]]>=a[i]) top--;
rf[i]=stk[top];
smr[i]=smr[rf[i]]+a[i]*(rf[i]-i);
stk[++top]=i;
}
ST();
for(int i=1;i<=Q;i++) q[i]={read(),read(),i};
sort(q+1,q+Q+1);
ll cnt=0;
for(int i=1,l=1,r=0;i<=Q;i++){
while(l>q[i].l) cnt+=gtl(--l,r);
while(r<q[i].r) cnt+=gtr(l,++r);
while(l<q[i].l) cnt-=gtl(l++,r);
while(r>q[i].r) cnt-=gtr(l,r--);
ans[q[i].id]=cnt;
}
for(int i=1;i<=Q;i++) write(ans[i]);
return fw,0;
}
即得易见平凡,仿照上例显然。留作习题答案略,读者自证不难。
反之亦然同理,推论自然成立。略去过程 ,由上可知证毕。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】