Description

影魔,奈文摩尔,据说有着一个诗人的灵魂。事实上,他吞噬的诗人灵魂早已成千上万。千百年来,他收集了各式各样的灵魂,包括诗人、牧师、帝王、乞丐、奴隶、罪人,当然,还有英雄。每一个灵魂,都有着自己的战斗力,而影魔,靠这些战斗力提升自己的攻击。奈文摩尔有 n 个灵魂,他们在影魔宽广的体内可以排成一排,从左至右标号 1 到 n。第 i个灵魂的战斗力为 k[i],灵魂们以点对的形式为影魔提供攻击力,对于灵魂对 i,j(i<j)来说,若不存在 k[s](i<s<j)大于 k[i]或者 k[j],则会为影魔提供 p1 的攻击力(可理解为:当 j=i+1 时,因为不存在满足 i<s<j 的 s,从而 k[s]不存在,这时提供 p1 的攻击力;当 j>i+1 时,若max{k[s]|i<s<j}<=min{k[i],k[j]},则提供p1的攻击力 ); 另一种情况,令c为k[i+1],k[i+2],k[i+3]......k[j-1]的最大值,若 c 满足:k[i]<c<k[j],或者 k[j]<c<k[i],则会为影魔提供 p2 的攻击力,当这样的 c 不存在时,自然不会提供这 p2 的攻击力;其他情况的点对,均不会为影魔提供攻击力。影魔的挚友噬魂鬼在一天造访影魔体内时被这些灵魂吸引住了,他想知道,对于任意一段区间[a,b],1<=a<b<=n,位于这些区间中的灵魂对会为影魔提供多少攻击力,即考虑 所有满足a<=i<j<=b的灵魂对i,j提供的攻击力之和。顺带一提,灵魂的斗力组成一个 1 到 n 的排列:k[1],k[2],...,k[n]。

Input

第一行 n,m,p1,p2
第二行 n 个数:k[1],k[2],...,k[n]
接下来 m 行,每行两个数 a,b,表示询问区间[a,b]中的灵魂对会为影魔提供多少攻击力。
1 <= n,m <= 200000;1 <= p1,p2 <= 1000

Output

共输出 m 行,每行一个答案,依次对应 m 个询问。

Sample Input

10 5 2 3
7 9 5 1 3 10 6 8 2 4
1 7
1 9
1 3
5 9
1 5

Sample Output

30
39
4
13
16
 
这种题目想+码花了快2小时我是不是药丸啊……
离线,从左到右扫,维护一下最大值的栈,用线段树做修改没了。
1A还是比较开心的。
#include<cstdio>
#include<algorithm>
#define MN 210000
#define lp (p<<1)
#define rp ((p<<1)|1)
#define ll long long
using namespace std; int read_p,read_ca;
inline int read(){
read_p=;read_ca=getchar();
while(read_ca<''||read_ca>'') read_ca=getchar();
while(read_ca>=''&&read_ca<='') read_p=read_p*+read_ca-,read_ca=getchar();
return read_p;
}
struct tree{int si,s,t[];ll sum;tree(){s=t[]=t[]=sum=;}}t[MN<<];
struct ask{int l,r,p;}qu[MN];
bool operator < (ask a,ask b){return a.r<b.r;}
int n,m,p1,p2,a[MN],q=,st[MN],num=,top;ll MMH[MN];
inline void hb(int p,int ty,int v){
if (ty){
if (t[p].s==) return;
t[p].t[]+=v;t[p].sum+=1LL*v*t[p].s;
}else{
if (t[p].s==t[p].si) return;
t[p].t[]+=v;t[p].sum+=1LL*v*(t[p].si-t[p].s);
}
}
inline void pd(int p){
if (t[p].t[]){
hb(lp,,t[p].t[]);
hb(rp,,t[p].t[]);
t[p].t[]=;
}
if (t[p].t[]){
hb(lp,,t[p].t[]);
hb(rp,,t[p].t[]);
t[p].t[]=;
}
}
void ADD(int p,int l,int r,int pos){
t[p].s++;
if (l==r) return;
pd(p);
int mid=l+r>>;
if (pos<=mid) ADD(lp,l,mid,pos);else ADD(rp,mid+,r,pos);
}
void del(int p,int l,int r,int pos){
t[p].s--;
if (l==r) return;
pd(p);
int mid=l+r>>;
if (pos<=mid) del(lp,l,mid,pos);else del(rp,mid+,r,pos);
}
void add(int p,int l,int r,int L,int R,int ty,int v){
if (ty){
if (t[p].s==) return;
}else if (t[p].s==t[p].si) return;
if (l==L&&r==R){hb(p,ty,v);return;}
pd(p);
int mid=l+r>>;
if (R<=mid) add(lp,l,mid,L,R,ty,v);else
if (L>mid) add(rp,mid+,r,L,R,ty,v);else
add(lp,l,mid,L,mid,ty,v),add(rp,mid+,r,mid+,R,ty,v);
t[p].sum=t[lp].sum+t[rp].sum;
}
ll ask(int p,int l,int r,int L,int R){
if (l==L&&r==R) return t[p].sum;
int mid=l+r>>;
pd(p);
if (R<=mid) return ask(lp,l,mid,L,R);else
if (L>mid) return ask(rp,mid+,r,L,R);else
return ask(lp,l,mid,L,mid)+ask(rp,mid+,r,mid+,R);
}
void build(int p,int l,int r){
t[p].si=r-l+;
if (l==r) return;
int mid=l+r>>;
build(lp,l,mid);build(rp,mid+,r);
}
int main(){
register int i,j;
n=read();m=read();p1=read();p2=read();
for (i=;i<=n;i++) a[i]=read();a[]=n+;
for (i=;i<=m;i++) qu[i].l=read(),qu[i].r=read(),qu[i].p=i;
sort(qu+,qu++m);st[top=]=;
build(,,n);
for (i=;i<=m;i++){
for (;q<=qu[i].r;q++){
for (j=top;a[st[j]]<a[q];j--);
if (q!=) add(,,n,st[j]+(j==),q-,,p1);
if (st[j]>) add(,,n,,st[j]-,,p2);
if (j!=top) add(,,n,st[j]+,q-,,p2);
while (a[st[top]]<a[q]) del(,,n,st[top--]);
ADD(,,n,st[++top]=q);
}
MMH[qu[i].p]=ask(,,n,qu[i].l,qu[i].r);
}
for (i=;i<=m;i++) printf("%lld\n",MMH[i]);
}

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]影魔

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

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

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

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

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

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

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

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

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

  7. 4826: [Hnoi2017]影魔

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

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

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

  9. 【LG3722】[HNOI2017]影魔

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

随机推荐

  1. jemeter——badboy导入的jmx文件自带元件解析

    线程组设置与解析 含义:1秒启动100个线程,每个线程循环调用20次请求  (包括FTP请求.Java请求.http请求,根据你提交的请求而定) delay thread creation until ...

  2. AO之Addins开发[杂谈1] Toolbar中添加一条分割线

    在XML代码中,给Item添加separator属性,需要从哪里打分割线,就将其设置为true即可.如下图所示: 如紫色框住的灰色竖线所示. 默认separator属性是false的,这个小东西极其隐 ...

  3. bzoj 2002 HNOI 2010 弹飞绵羊

    Description 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一条直线摆上n个装置,每个装置 ...

  4. MySQL 加锁处理分析-转载

    来自何登成的技术博客     1.1    MVCC:Snapshot Read vs Current Read    2 1.2    Cluster Index:聚簇索引    3 1.3     ...

  5. LVS-DR集群搭建

    安装LVS 下载源码包,安装时需要根据自己的内核,下载 ipvsadm-1.26.tar.gz的源码包,在进行编译安装以后,我们需要检查必需包是否安装: 1.对内核文件做链接 # uname -r 2 ...

  6. Golang中的坑二

    Golang中的坑二 for ...range 最近两周用Golang做项目,编写web服务,两周时间写了大概五千行代码(业务代码加单元测试用例代码).用Go的感觉很爽,编码效率高,运行效率也不错,用 ...

  7. vue监听scroll使用报错的解决办法

    错误说明:在切换路由以后,依旧在其他页面触发了scroll有关的函数, 错误原因:在spa项目中,window对象是不变的,所以每次使用后需要销毁. 解决办法:vue的生命周期destroyed中销毁 ...

  8. Q:java中serialVersionUID的作用

    @转载自:http://www.cnblogs.com/guanghuiqq/archive/2012/07/18/2597036.html   简单来说,Java的序列化机制是通过在运行时判断类的s ...

  9. 人工智能一:Al学习路线

    想要跨入AI的大门,如何跨?终于找到了一套学习方法 努力向你靠近 2017-12-03 07:14:51 当下人工智能领域的发展已经有了燎原之势,麦肯锡全球研究院就认为人工智能促进对社会的转变速度将比 ...

  10. [SDOI2009]E&D

    题目描述 小E 与小W 进行一项名为“E&D”游戏. 游戏的规则如下: 桌子上有2n 堆石子,编号为1..2n.其中,为了方便起见,我们将第2k-1 堆与第2k 堆 (1 ≤ k ≤ n)视为 ...