题目链接:影魔

  这道题就是去年序列的弱化版啊……

  我们枚举最大值的位置\(i\),找出左边第一个比\(a_i\)大的位置\(l\),右边第一个比\(a_i\)大的位置\(r\),然后我们分开考虑一下\(p_1\)和\(p_2\)的贡献。

  首先由于\(a_i\)为最大值,那么左端点不会小于\(l\),右端点不会大于\(r\)。

  容易发现只有左端点为\(l\),右端点为\(r\)才会产生\(p_1\)的贡献。

  然后产生\(p_2\)贡献的有两种:一种是左端点为\(l\),右端点在区间\((i,r)\)中;另一种是左端点区间\((l,i)\)中,右端点为\(r\)。

  还有一种情况需要考虑,就是左端点和右端点差为\(1\),会产生\(p_1\)的贡献。对每个询问直接计算就可以了。

  所以这个问题可以抽象到二维平面上。有一些点和一些线段都有权值,每次询问某个矩形内部的权值和。

  于是离线排序+扫描线+树状数组即可。

  下面贴代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define maxn 200010 using namespace std;
typedef long long llg; struct data{
int l,r,x,b,z;
data(int A=0,int B=0,int C=0,int D=0,int E=0):l(A),r(B),x(C),b(D),z(E){}
bool operator < (const data &h)const{return x<h.x;}
}s1[maxn<<1],s2[maxn*3];
int n,m,p1,p2,S[maxn],top,ls;
int a[maxn],le[maxn],ri[maxn];
llg ans[maxn],c1[maxn],c2[maxn]; int getint(){
int w=0;bool q=0;
char c=getchar();
while((c>'9'||c<'0')&&c!='-') c=getchar();
if(c=='-') c=getchar(),q=1;
while(c>='0'&&c<='9') w=w*10+c-'0',c=getchar();
return q?-w:w;
} void add(int x,int y){for(int i=x;i<=n;i+=i&(-i)) c1[i]+=y,c2[i]+=1ll*x*y;}
llg sum(int x){
llg t=0;
for(int i=x;i;i-=i&(-i)) t+=(x+1)*c1[i]-c2[i];
return t;
} int main(){
File("sf");
scanf("%d %d %d %d",&n,&m,&p1,&p2);
a[0]=a[n+1]=n+1; S[top=1]=0;
for(int i=1;i<=n+1;i++){
if(i<=n) a[i]=getint();
while(a[S[top]]<a[i]) ri[S[top--]]=i;
le[i]=S[top]; S[++top]=i;
}
for(int i=1,l,r;i<=m;i++){
l=getint(),r=getint(); ans[i]+=(r-l)*p1;
s1[i]=data(l,r,l-1,i,-1);
s1[i+m]=data(l,r,r,i,1);
}
sort(s1+1,s1+m*2+1);
for(int i=1;i<=n;i++){
if(le[i] && ri[i]<=n) s2[++ls]=data(le[i],le[i],ri[i],0,p1);
if(le[i] && ri[i]>i+1) s2[++ls]=data(i+1,ri[i]-1,le[i],0,p2);
if(ri[i]<=n && i>le[i]+1) s2[++ls]=data(le[i]+1,i-1,ri[i],0,p2);
}
sort(s2+1,s2+ls+1); int n1=1,n2=1;
while(!s1[n1].x) n1++;
for(int i=1;n1<=m*2 && i<=n;i++){
while(n2<=ls && s2[n2].x==i){
add(s2[n2].r+1,-s2[n2].z);
add(s2[n2].l,s2[n2].z),n2++;
}
while(n1<=m*2 && s1[n1].x==i){
ans[s1[n1].b]+=s1[n1].z*(sum(s1[n1].r)-sum(s1[n1].l-1));
n1++;
}
}
for(int i=1;i<=m;i++) printf("%lld\n",ans[i]);
return 0;
}

BZOJ 4826 【HNOI2017】 影魔的更多相关文章

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

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

  2. BZOJ:4826: [Hnoi2017]影魔

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

  3. ●BZOJ 4826 [Hnoi2017]影魔

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=4826 题解: 主席树,单调栈 以前还没做过这种维护信息的题,感觉好奇妙. 每对相邻的两个数所 ...

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

    https://www.lydsy.com/JudgeOnline/problem.php?id=4826 年少不知空间贵,相顾mle空流泪. 和上一道主席树求的东西差不多,求两种对 1. max(a ...

  5. BZOJ 4826: [Hnoi2017]影魔 单调栈+可持久化线段树

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

  6. BZOJ 4826 [Hnoi2017]影魔 ——扫描线 单调栈

    首先用单调栈和扫描线处理出每一个数左面最近的比他大的数在$l[i]$,右面最近的比他大的数$r[i]$. 然后就可以考虑每种贡献是在什么时候产生的. 1.$(l[i],r[i])$产生$p1$的贡献 ...

  7. bzoj 4826: [Hnoi2017]影魔【单调栈+树状数组+扫描线】

    参考:https://www.cnblogs.com/lcf-2000/p/6789680.html 这是一个相对码量少的做法,用到了区间修改区间查询的树状数组,详见:www.cnblogs.com/ ...

  8. 4826: [Hnoi2017]影魔

    4826: [Hnoi2017]影魔 https://lydsy.com/JudgeOnline/problem.php?id=4826 分析: 莫队+单调栈+st表. 考虑如何O(1)加入一个点,删 ...

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

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

  10. 【LG3722】[HNOI2017]影魔

    [LG3722][HNOI2017]影魔 题面 洛谷 题解 先使用单调栈求出\(i\)左边第一个比\(i\)大的位置\(lp_i\),和右边第一个比\(i\)大的位置\(rp_i\). 考虑\(i\) ...

随机推荐

  1. <转>jmeter(五)JDBC Request

    本博客转载自:http://www.cnblogs.com/imyalost/category/846346.html 个人感觉不错,对jmeter讲解非常详细,担心以后找不到了,所以转发出来,留着慢 ...

  2. php_study progress(1)

    PHP是一种语法简单.功能强大的网络编程语言.在语法格式上,PHP借鉴了广泛流行的C.Java和Perl等编程语言的特点,非常类似于C语言,但比C语言更简单,易学和易用,因此特别适合于学习过C语言,有 ...

  3. The Little Prince-12/06

    The Little Prince-12/06 “That doesn't matter. Draw me a sheep.” When the prince ask the planet to dr ...

  4. i2c调试碰到的问题

    i2c eeprom i2cget两次结果不一致 i2cset没成功. device里只看到50,却冒出了51地址. i2ctools是针对8bit地址的,而我们的eeprom都是用16bit add ...

  5. Linux下php添加memcache扩展

    很多时候我们都会遇到在已经安装的php中添加其它的扩展. 那我们应该怎么做呢? 这样做.(我们的nginx和php都是已经安装好了的,这里就不做赘述了) 首先,我们需要下载php的memcache扩展 ...

  6. Mysql去掉html标签函数

    函数 SET GLOBAL log_bin_trust_function_creators=; DROP FUNCTION IF EXISTS fnStripTags; DELIMITER | CRE ...

  7. 应使用sqlplus代替tnsping进行oracle连通性测试

    一直以来,都习惯于tnsping alias测试确定使用了那个sqlnet.ora,并测试连通性.最近在制作系统的安装包,为了轻量级以及提高实施效率,全部客户端使用oracle instant cli ...

  8. RadioButton在数据列表中实现单选功能

    在服务器端动态生成的name总是不断变化,故需手动实现单选 ; <html xmlns="http://www.w3.org/1999/xhtml"> <head ...

  9. Plantuml画图工具

    1,Plantuml画图工具 安装指南: Mac sublimetext http://blog.csdn.net/zhangjikuan/article/details/53365730 win i ...

  10. python操作串口

    import serial test = serial.Serial("COM1",115200)#这里就已经打开了串口 print(test.portstr) test.writ ...