#include<bits/stdc++.h>
#define maxn 200010
using namespace std;
int a[maxn],st[maxn][2],top,L[maxn],R[maxn],root[2][maxn];
struct node{int x,y;}A[maxn];
struct Node{int x,yl,yr;}B[maxn<<1];
long long num;
bool cmp1(node p,node q){return p.x<q.x;}
bool cmp2(Node p,Node q){return p.x<q.x;}
struct TREE{
int lc[maxn*30],rc[maxn*30],tag[maxn*30],tot;
long long sum[maxn*30];
void insert(int pre,int &k,int l,int r,int opl,int opr){
k=++tot;
tag[k]=tag[pre];
sum[k]=sum[pre]+opr-opl+1;
lc[k]=lc[pre];rc[k]=rc[pre];
if(l>=opl&&r<=opr){tag[k]++;return;}
int mid=(l+r)>>1;
if(opr<=mid) insert(lc[pre],lc[k],l,mid,opl,opr);
else if(opl>mid) insert(rc[pre],rc[k],mid+1,r,opl,opr);
else {
insert(lc[pre],lc[k],l,mid,opl,mid);
insert(rc[pre],rc[k],mid+1,r,mid+1,opr);
}
}
void query(int x,int pre,int l,int r,int opl,int opr){
if(l>=opl&&r<=opr){num+=sum[x]-sum[pre];return;}
int mid=(l+r)>>1;
if(opr<=mid) {
num+=(tag[x]-tag[pre])*(opr-opl+1);
query(lc[x],lc[pre],l,mid,opl,opr);
}
else if(opl>mid) {
num+=(tag[x]-tag[pre])*(opr-opl+1);
query(rc[x],rc[pre],mid+1,r,opl,opr);
}
else {
num+=(tag[x]-tag[pre])*(mid-opl+1);
query(lc[x],lc[pre],l,mid,opl,mid);
num+=(tag[x]-tag[pre])*(opr-mid);
query(rc[x],rc[pre],mid+1,r,mid+1,opr);
}
}
}tr[2];
int main(){
int n,m,p1,p2;
scanf("%d%d%d%d",&n,&m,&p1,&p2);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
st[top][0]=n+1;st[top][1]=0;
for(int i=1;i<=n;i++){
while(top&&a[i]>st[top][0])top--;
L[i]=st[top][1];
st[++top][0]=a[i];
st[top][1]=i;
}
st[top=0][0]=n+1;
st[top][1]=n+1;
for(int i=n;i;i--){
while(top&&a[i]>st[top][0])top--;
R[i]=st[top][1];
st[++top][0]=a[i];
st[top][1]=i;
}
int cnt=0;
for(int i=1;i<=n;i++)
if(L[i]&&R[i]<=n){
A[++cnt].x=L[i];
A[cnt].y=R[i];
}
sort(A+1,A+cnt+1,cmp1);
int now=1;
for(int i=1;i<=cnt;i++){
while(now+1<A[i].x)root[0][now+1]=root[0][now],now++;
tr[0].insert(root[0][now],root[0][A[i].x],1,n,A[i].y,A[i].y);
now=A[i].x;
}
while(now!=n)root[0][now+1]=root[0][now++];
cnt=0;
for(int i=1;i<=n;i++){
if(R[i]!=i+1 && L[i]){
B[++cnt].x=L[i];
B[cnt].yl=i+1;
B[cnt].yr=R[i]-1;
}
if(L[i]!=i-1 && R[i]<=n){
B[++cnt].x=R[i];
B[cnt].yl=L[i]+1;
B[cnt].yr=i-1;
}
}
sort(B+1,B+cnt+1,cmp2);
now=1;
for(int i=1;i<=cnt;i++){
while(now+1<B[i].x)root[1][now+1]=root[1][now],now++;
tr[1].insert(root[1][now],root[1][B[i].x],1,n,B[i].yl,B[i].yr);
now=B[i].x;
}
while(now!=n)root[1][now+1]=root[1][now++];
int l,r;
long long ans;
while(m--){
scanf("%d%d",&l,&r);
num=0;
tr[0].query(root[0][r],root[0][l-1],1,n,l,r);
ans=num*p1;num=0;
tr[1].query(root[1][r],root[1][l-1],1,n,l,r);
ans+=num*p2;
ans+=(r-l)*p1;
cout<<ans<<endl;
}
return 0;
}

[AH2017/HNOI2017] 影魔 - 线段树的更多相关文章

  1. 洛谷P3722 [AH2017/HNOI2017]影魔(线段树)

    题意 题目链接 Sol 题解好神仙啊qwq. 一般看到这种考虑最大值的贡献的题目不难想到单调数据结构 对于本题而言,我们可以预处理出每个位置左边第一个比他大的位置\(l_i\)以及右边第一个比他大的位 ...

  2. P3722 [AH2017/HNOI2017]影魔(单调栈+扫描线+线段树)

    题面传送门 首先我们把这两个贡献翻译成人话: 区间 \([l,r]\) 产生 \(p_1\) 的贡献当且仅当 \(a_l,a_r\) 分别为区间 \([l,r]\) 的最大值和次大值. 区间 \([l ...

  3. 刷题总结——影魔(HNOI2017 BZOJ4826 线段树+扫描线)

    题目: Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样 的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄 ...

  4. bzoj 4826: [Hnoi2017]影魔 [主席树 单调栈]

    4826: [Hnoi2017]影魔 题意:一个排列,点对\((i,j)\),\(p=max(i+1,j-1)\),若\(p<a_i,a_j\)贡献p1,若\(p\)在\(a_1,a_2\)之间 ...

  5. [BZOJ4826][HNOI2017]影魔(主席树)

    4826: [Hnoi2017]影魔 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 669  Solved: 384[Submit][Status][ ...

  6. [AH2017/HNOI2017]影魔

    嘟嘟嘟 这题真的挺神的,我是真没想出来. 洛谷的第一篇题解说的非常妙,实在是佩服. 就是我们首先预处理出对于第\(i\)个数,在\(i\)左边比第一个比\(i\)大的数\(l_i\),在\(i\)右边 ...

  7. [AH2017/HNOI2017]影魔(主席树+单调栈)

    设\(l[i]\)为i左边第一个比i大的数的下标.\(r[i]\)为i右边第一个比i大的数的下标. 我们把\(p1,p2\)分开考虑. 当产生贡献为\(p1\)时\(i\)和\(j\)一定满足,分别为 ...

  8. luogu P3722 [AH2017/HNOI2017]影魔

    传送门 我太弱了,只会乱搞,正解是不可能正解的,这辈子不可能写正解的,太蠢了又想不出什么东西,就是乱搞这种东西,才能维持得了做题这样子 考虑将询问离线,按右端点排序,并且预处理出每个位置往前面第一个大 ...

  9. 洛谷P3722 影魔 [AH2017/HNOI2017] 线段树+扫描线

    正解:线段树+扫描线 解题报告: 传送门! 先理解一下这道题,大概是这样儿的: 对于一个点对,如果他们的两端是这段区间的最大值和次大值,那么他们会有p1的贡献 如果他们的两端是最大值和一个非次大值,那 ...

随机推荐

  1. df du 文件空间管理 命令

     df  可以查看一级文件夹大小.使用比例.档案系统及其挂入点,但对文件却无能为力. du 可以查看文件及文件夹的大小.     df:常用   df -h    以易读形式显示 磁盘空间 linux ...

  2. Day4前端学习之路——背景边框列表链接和更复杂的选择器

    课程目标 掌握 CSS 稍微复杂的一些选择器,还有背景,边框等一些 CSS 样式属性 主要内容: 背景属性 边框 列表 链接 其他选择器 选择器概览:https://www.w3school.com. ...

  3. Git Gui for Windows下载(pull)的正确操作方法

  4. 关于ETH/BTC区块的监控

    此次我写的是一个小型的shell, 链接钉钉的机器人, 使用过的应该会比较娴熟的了,下面就简述一下把 主要的功能就是, 当发现本地数据库区块跟网络上的区块差距相差较大的时候就代表, 数据同步有问题, ...

  5. 单页应用(SPA,Single-page-App)和多页应用(MPA,Multi-page App)的区别

    单页应用(SPA,Single-page-App)和多页应用(MPA,Multi-page App)的区别 参考博客:https://www.jianshu.com/p/4c9c29967dd6

  6. 学习MVC框架,处理分页和删除分页转跳的问题

    第一次写博客,文采不好请多见谅,这里主要是写一下,自己是如何处理分页问题,我想初学者也遇到过这个问题. 分页的情况下,编辑信息有返回和编辑2个按钮,操作后都是应该返回原分页界面,使用TempData把 ...

  7. 【HDU - 2859 】Phalanx (dp 最大对称子图)

    Phalanx 先搬翻译 Descriptions: 给你一个矩阵,只由小写或大写字母构成.求出它的最大对称子矩阵的边长. 其中对称矩阵是一个k*k的矩阵,它的元素关于从左下角到右上角的对角线对称.例 ...

  8. 史上最全的Java高级技术点,全是Java高级进阶技术,几乎包含了Java后端的所有知识点

    史上最全的Java高级技术点,全是Java高级进阶技术,几乎包含了Java后端的所有知识点 1

  9. 开源版 nignx 不支持 ntml 验证

    最近在一个环境相对比较复杂(F5+nginx)的项目中部署系统,系统要集成windows域验证来实现单点登录(即使用windows账户直接登录系统,不用输入账号密码).这里就遇到问题了,域认证很不稳定 ...

  10. libmodbus库linux 嵌入式设备中的使用

    libmodbus库的交叉编译:1]到libmodbus官网https://libmodbus.org/download/下载安装包,内部自带configure文件,官网推荐v3.1.6稳定版.另外注 ...