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 个询问。
 
对于点 $i$,用单调栈求出左边和右边第一个大于 $i$ 的位置,记为 $l[i]$ 与 $r[i]$.    
那么 $(l[i],r[i])$ 会产生 $p1$ 的贡献.  
左端点为 $l[i]$,则如果右端点在 $[i+1,r-1]$ 的话都会产生 $p1$ 的贡献. 
而右端点在 $r[i]$,左端点在 $[l+1,i-1]$ 都会产生 $p2$ 的贡献.   
因为这个东西有一个端点是固定的,另一个区间是连续区间,所以可以用主席树来维护.  
由于 $pushdown$ 函数比较麻烦,这里用的标记永久化.   
#include <cstring>
#include <cstdio>
#include <stack>
#include <string>
#include <vector>
#include <algorithm>
#define N 200005
#define ll long long
using namespace std;
void setIO(string s) {
string in=s+".in";
string out=s+".out";
freopen(in.c_str(),"r",stdin);
// freopen(out.c_str(),"w",stdout);
}
int n,m,tp,edges;
int p1,p2;
int val[N];
int sta[N];
int L[N],R[N];
int hd[N];
int tot;
int rtl[N];
int rtr[N];
struct Edge {
int x;
int l;
int r;
int v;
int nex;
}e[N*3];
struct node {
int ls;
int rs;
ll tag;
ll sum;
}t[N*80];
void add(int u,int l,int r,int v) {
e[++edges].nex=hd[u];
hd[u]=edges;
e[edges].l=l;
e[edges].r=r;
e[edges].x=u;
e[edges].v=v;
}
int newnode() {
return ++tot;
}
int update(int x,int l,int r,int L,int R,int v) {
if(L>R) {
return x;
}
int now=newnode();
t[now]=t[x];
t[now].sum+=(ll)(min(r,R)-max(l,L)+1)*v;
if(l>=L&&r<=R) {
t[now].tag+=v;
return now;
}
int mid=(l+r)>>1;
if(L<=mid) {
t[now].ls=update(t[x].ls,l,mid,L,R,v);
}
if(R>mid) {
t[now].rs=update(t[x].rs,mid+1,r,L,R,v);
}
return now;
}
ll query(int x,int l,int r,int L,int R) {
if(!x) {
return 0;
}
if(l>=L&&r<=R) {
return t[x].sum;
}
int mid=(l+r)>>1;
ll re=(ll)t[x].tag*(min(r,R)-max(l,L)+1);
if(L<=mid) {
re+=query(t[x].ls,l,mid,L,R);
}
if(R>mid) {
re+=query(t[x].rs,mid+1,r,L,R);
}
return re;
}
int main() {
// setIO("input");
int i,j;
scanf("%d%d%d%d",&n,&m,&p1,&p2);
for(i=1;i<=n;++i) {
scanf("%d",&val[i]);
}
for(i=1;i<=n;++i) {
while(tp&&val[sta[tp]]<val[i]) {
--tp;
}
L[i]=sta[tp];
sta[++tp]=i;
}
sta[tp=0]=n+1;
for(i=n;i>=1;--i) {
while(tp&&val[sta[tp]]<val[i]) {
--tp;
}
R[i]=sta[tp];
sta[++tp]=i;
}
for(i=1;i<=n;++i) {
add(L[i],R[i],R[i],p1);
add(L[i],i+1,R[i]-1,p2);
add(R[i],L[i]+1,i-1,p2);
}
// 向右
for(i=1;i<=n;++i) {
rtl[i]=rtl[i-1];
for(j=hd[i];j;j=e[j].nex) {
if(e[j].l>i) {
rtl[i]=update(rtl[i],1,n,max(1,e[j].l),min(n,e[j].r),e[j].v);
}
}
if(i!=n) {
rtl[i]=update(rtl[i],1,n,i+1,i+1,p1);
}
}
for(i=n;i>=1;--i) {
rtr[i]=rtr[i+1];
for(j=hd[i];j;j=e[j].nex) {
if(e[j].r<i) {
rtr[i]=update(rtr[i],1,n,max(1,e[j].l),min(n,e[j].r),e[j].v);
}
}
}
while(m--) {
int x,y;
scanf("%d%d",&x,&y);
ll ans=0ll;
ans+=query(rtl[y],1,n,x,y);
ans-=query(rtl[x-1],1,n,x,y);
ans+=query(rtr[x],1,n,x,y);
ans-=query(rtr[y+1],1,n,x,y);
printf("%lld\n",ans);
}
return 0;
}

  

BZOJ 4826: [Hnoi2017]影魔 单调栈+可持久化线段树的更多相关文章

  1. 【bzoj4826】[Hnoi2017]影魔 单调栈+可持久化线段树

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

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

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

  3. 【bzoj3956】Count 单调栈+可持久化线段树

    题目描述 输入 输出 样例输入 3 2 0 2 1 2 1 1 1 3 样例输出 0 3 题解 单调栈+可持久化线段树 本题是 bzoj4826 的弱化版(我为什么做题总喜欢先挑难的做QAQ) $k$ ...

  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. BZOJ:4826: [Hnoi2017]影魔

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

  6. [BZOJ 3218] A + B Problem 【可持久化线段树 + 网络流】

    题目连接:BZOJ - 3218 题目分析 题目要求将 n 个点染成黑色或白色,那么我们可以转化为一个最小割模型. 我们规定一个点 i 最后属于 S 集表示染成黑色,属于 T 集表示染成白色,那么对于 ...

  7. Bzoj 4408: [Fjoi 2016]神秘数 可持久化线段树,神题

    4408: [Fjoi 2016]神秘数 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 177  Solved: 128[Submit][Status ...

  8. BZOJ 4408: [Fjoi 2016]神秘数 可持久化线段树

    4408: [Fjoi 2016]神秘数 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4408 Description 一个可重复数字集 ...

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

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

随机推荐

  1. RabbitMQ操作代码封装

    1.Message.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; u ...

  2. Spring事务调用类自己方法失效解决办法和原因

    问题 正常情况下,我们都是在controller里调用service里的方法,这个方法如果需要加事务,就在方法上加上@Transactional,这样是没问题的,事务会生效. 可是如果像下面这样,绕以 ...

  3. JAVA PTA 7-1 作品评分 (10 分)

    全国中小学生Scratch作品大赛拉开了序幕.每个参赛选手可以通过网络直接上传作品.本次比赛人人可做评委.每个网络评委可以通过网络对每一件作品进行打分.评分系统也是请程序高手设计的,能自动去掉一个最高 ...

  4. 【More Effective C++ 条款1】仔细区别pointers和references

    1)操作符的差别 指针使用"*"和"->"操作符,而引用使用"."操作符 2)初始化的差别 有空指针,但是没有空引用,和const对象 ...

  5. scala练习题--万年历

     使用方法去完成 import scala.io.StdIn object work1 { def main(args: Array[String]): Unit = { // 1.先输出提示语句,并 ...

  6. jquery动画控制非css属性

    JQuery的animate()方法可以通过渐变的更改CSS属性来实现简单的动画效果, 比如 $("#box").animate({height:"300px" ...

  7. webapi 集成NLog

    参考项目代码:SwaggerDemoApi 安装 打开nuget管理器--->搜索nlog,安装箭头所指的两个文件到你的项目中,config安装到你的API项目即可,nlog文件安装到你用得到n ...

  8. MySQL——数据库操作

    1.创建数据库 登录MySQL服务后,使用create命令创建数据库 # 登录MySQL进入终端 mysql -u root -p # 之后输入命令 create database database_ ...

  9. 将canvas中左上角的原点坐标位置改为左下角

    在使用canvas的时候,原点坐标在左上角,这个很犯人,因为一般的坐标基本都是在左下角,即笛卡尔坐标系,那怎么进行转变呢,在这里用到了canvas的translate,rotate,和scale进行转 ...

  10. Vue开发日志

    一 搭建环境 mac 安装node brew install node 安装vue 全家桶 npm install -g vue-cli 选择一个目录做初始化 vue init webpack myp ...