[AH2017/HNOI2017] 影魔 - 线段树
2024-10-08 08:50:40
#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;
}
最新文章
- dom2和dom3
- .NET Core竟然无法在Mac下进行build
- 【BZOJ】【4003】【JLOI2015】城池攻占
- Vijos1404 遭遇战 最短路,dijkstra,堆
- As3 里的正则相关
- ipsec vpn私网数据大量掉包问题
- React-native 初始化项目很慢
- html标记语言 --框架
- PCA降维实验代码
- 颠倒的价牌|2013年蓝桥杯A组题解析第四题-fishers
- R语言数据挖掘相关包总结-转帖
- mybatis缓存(一,二级别)
- bzoj千题计划187:bzoj1770: [Usaco2009 Nov]lights 燈 (高斯消元解异或方程组+枚举自由元)
- [svc]centos6上部署openvpn+gg二步认证
- ajax缓存和编码问题
- HTML的设计与应用
- 在 Azure 虚拟机中配置 Always On 可用性组(经典)
- thread_local变量(转)
- WPF&;Silverlight5 常用功能差异
- C# 二维码扫描
热门文章
- windows10 CTCP
- docker device or resource busy
- tomcat 日志
- 使用FIO工具测试块存储性能
- LVS服务原理以及搭建
- 检测APK是否存在Janus漏洞步骤
- 静态SRAM芯片工作原理
- 常量, char[], const char[], char*, const char*, char* const以及const char* const的详解
- 简单说说常用的css选择器
- 利用ARP欺骗进行MITM(中间人攻击)