[AH2017/HNOI2017] 影魔 - 线段树
#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] 影魔 - 线段树的更多相关文章
- 洛谷P3722 [AH2017/HNOI2017]影魔(线段树)
题意 题目链接 Sol 题解好神仙啊qwq. 一般看到这种考虑最大值的贡献的题目不难想到单调数据结构 对于本题而言,我们可以预处理出每个位置左边第一个比他大的位置\(l_i\)以及右边第一个比他大的位 ...
- P3722 [AH2017/HNOI2017]影魔(单调栈+扫描线+线段树)
题面传送门 首先我们把这两个贡献翻译成人话: 区间 \([l,r]\) 产生 \(p_1\) 的贡献当且仅当 \(a_l,a_r\) 分别为区间 \([l,r]\) 的最大值和次大值. 区间 \([l ...
- 刷题总结——影魔(HNOI2017 BZOJ4826 线段树+扫描线)
题目: Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样 的灵魂,包括诗人.牧师.帝王.乞丐.奴隶.罪人,当然,还有英雄 ...
- bzoj 4826: [Hnoi2017]影魔 [主席树 单调栈]
4826: [Hnoi2017]影魔 题意:一个排列,点对\((i,j)\),\(p=max(i+1,j-1)\),若\(p<a_i,a_j\)贡献p1,若\(p\)在\(a_1,a_2\)之间 ...
- [BZOJ4826][HNOI2017]影魔(主席树)
4826: [Hnoi2017]影魔 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 669 Solved: 384[Submit][Status][ ...
- [AH2017/HNOI2017]影魔
嘟嘟嘟 这题真的挺神的,我是真没想出来. 洛谷的第一篇题解说的非常妙,实在是佩服. 就是我们首先预处理出对于第\(i\)个数,在\(i\)左边比第一个比\(i\)大的数\(l_i\),在\(i\)右边 ...
- [AH2017/HNOI2017]影魔(主席树+单调栈)
设\(l[i]\)为i左边第一个比i大的数的下标.\(r[i]\)为i右边第一个比i大的数的下标. 我们把\(p1,p2\)分开考虑. 当产生贡献为\(p1\)时\(i\)和\(j\)一定满足,分别为 ...
- luogu P3722 [AH2017/HNOI2017]影魔
传送门 我太弱了,只会乱搞,正解是不可能正解的,这辈子不可能写正解的,太蠢了又想不出什么东西,就是乱搞这种东西,才能维持得了做题这样子 考虑将询问离线,按右端点排序,并且预处理出每个位置往前面第一个大 ...
- 洛谷P3722 影魔 [AH2017/HNOI2017] 线段树+扫描线
正解:线段树+扫描线 解题报告: 传送门! 先理解一下这道题,大概是这样儿的: 对于一个点对,如果他们的两端是这段区间的最大值和次大值,那么他们会有p1的贡献 如果他们的两端是最大值和一个非次大值,那 ...
随机推荐
- javascript A*算法 寻路算法 获取最短路径算法
//A算法 自动寻路 路径 class GetAutoPath{ constructor(id, map, sPos, ePos, mapArr){ //this.type = id.type; th ...
- ELK logstash 各种报错
1.logstash 启动后数据传输了,但是 ElasticSearch 中没有生成索引,查看logstash日志,报错如下 [2018-06-08T14:46:25,387][WARN ] [log ...
- 维基逃离MySQL 力挺开源数据库 MariaDB
近日全球著名百科类网站维基百科宣布,将不会再用MySQL数据库,据国外媒体报道,很多年,MySQL一直是热门的开源数据库,不过在被甲骨文收购后,面临闭源的风险.因此维基百科将切换到另外一款开源数据库M ...
- asp.net网站作为websocket服务端的应用该如何写
最近被websocket的一个问题困扰了很久,有一个需求是在web网站中搭建websocket服务.客户端通过网页与服务器建立连接,然后服务器根据ip给客户端网页发送信息. 其实,这个需求并不难,只是 ...
- day1 对java的认识
对java的认识 1.java是一门跨平台的语言,由jvm进行预编译,转换成类似伪代码一样的东西,最后再转换成机器语言. 2.程序是由数据结构和算法构成,其他所有的工具类,方法都是为数据结构或者算法服 ...
- python len函数(41)
在python中除了print函数之外,len函数和type函数应该算是使用最频繁的API了,操作都比较简单. 一.len函数简介 返回对象的长度(项目数)参数可以是序列(例如字符串str.元组tup ...
- go 并发编程
进程 线程 协程 设置golang运行cpu数 1.主线程和协程同时执行 package main import ( "fmt" "strconv" " ...
- ipad的12系统里提示更新到ipdos13,原来安装在12上的app是不是没有了,要重新下载
ipad的12系统里提示更新到ipdos13,原来安装在12上的app是不是没有了,要重新下载 更新后原来的WiFi密码都还在不用重新连接WiFi,桌面壁纸也是原来12系统上的 在Ipad的设置里将1 ...
- Java 代码块详解
注:本文出自博主 Chloneda:个人博客 | 博客园 | Github | Gitee | 知乎 注:本文原链接:https://www.cnblogs.com/chloneda/p/java-c ...
- 面试再问ThreadLocal,别说你不会!
ThreadLocal是什么 以前面试的时候问到ThreadLocal总是一脸懵逼,只知道有这个哥们,不了解他是用来做什么的,更不清楚他的原理了.表面上看他是和多线程,线程同步有关的一个工具类,但其 ...