#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. pytorch之 regression

    import torch import torch.nn.functional as F import matplotlib.pyplot as plt # torch.manual_seed(1) ...

  2. Oracle 重启监听

    对于DBA来说,启动和关闭oracle监听器是很基础的任务,但是Linux系统管理员或者程序员有时也需要在开发数据库中做一些基本的DBA操作,因此了解一些基本的管理操作对他们来说很重要. 本文将讨论用 ...

  3. zabbix-proxy配置文件参数说明

    配置文件路径: /etc/zabbix/zabbix_proxy.conf Server=10.0.0.10 #<===指定zabbix server的ip地址或主机名 Hostname=zab ...

  4. -bash: warning: setlocale: LC_CTYPE: cannot change locale (zh_CN.UTF-8mb4): No such file or directory

    前几天登录服务器发现出现了这些个警告,一直没时间去处理他,今天难得有空,处理一下并记录下来,希望可以帮助到有需要的朋友. 警告信息如下: Last login: Tue May :: from 192 ...

  5. css权重导致的样式不生效问题

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. Chrome开发者工具使用指南

    前言 工欲善其事,必先利其器. 在前端工作中,我们常常使用到Chrome开发者工具去做各种各样的事情. 但是您真的了解这些开发者工具吗? 官方文档还是挺详细的:chrome-devtools文档. 但 ...

  7. Flink知识散点

    1.KeyBy 操作后,只有当 Key 的数量大于算子的并发实例数才能获得较好的计算性能. A.而若Key 的数量比实例数量少,就会导致部分实例收不到数据,这些实例就得不到执行,这些实例的计算能力得不 ...

  8. 关于建立 Carbon Forum 后 设置访问链接的问题

    如果不想访问的是根目录可以如下设置. location /cf { try_files $uri $uri/ /cf/index.php?$query_string;} 这样访问 /cf 目录就可以访 ...

  9. 【已解决】pyinstaller UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xce in position 110: invalid continuation byte

    转载自勤奋的小青蛙本文链接地址: [已解决]pyinstaller UnicodeDecodeError: ‘utf-8’ codec can’t decode byte 0xce in positi ...

  10. 《自拍教程19》aapt_apk信息查看工具

    aapt命令行工具介绍 aapt.exe(Linux/Ubuntu/imac操作系统下是未带后缀的aapt), 是android sdk自带的用于打包apk,解析apk的命令行工具软件. aapt.e ...