https://www.lydsy.com/JudgeOnline/problem.php?id=4826

年少不知空间贵,相顾mle空流泪。

和上一道主席树求的东西差不多,求两种对

1. max(a[(i,j)])<min(a[i],a[j]),[i,j]这一对贡献p1.

2. max(a[(i,j)])在a[i],a[j]之间,[i,j]这一对贡献p2.

第一种和bzoj3956那道一样,但是因为是排列所以没必要去重了。

第二种同样是单调栈求lp,rp,每个位置的lp分别和[ i+1 , rp-1 ], rp分别和[ lp+1 , i-1 ], 构成了贡献p2的数对。

因此贡献为p2的数对要区间修改,因为方便(不用downdata)(其实是因为我抄的代码就是标记永久化)所以写了标记永久化,标记永久化真的挺好用的嘻嘻。

感觉写了这道题终于有点摸到主席树的门路了,其实就是找和维护两个区间进行限制的值(找和维护一个二维块),一层线段树一层前缀和(只是有传递性不一定是实际意义的和)。

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define LL long long
const int maxn=;
LL n,m,p1,p2;
LL a[maxn]={},sta[maxn]={},tail=;
LL lp[maxn]={},rp[maxn]={},rt[maxn]={};
LL lc[maxn*]={},rc[maxn*]={},siz[maxn*]={},ad[maxn*]={},tot=;
struct nod{
LL x,l,r,v;
}e[maxn*];
LL cnt=;
bool mcmp(nod aa,nod bb){ return aa.x<bb.x; }
LL read(){
LL w=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){w=w*+ch-'';ch=getchar();}
return w*f;
}
void build(LL &x,LL y,LL l,LL r,LL z,LL zl,LL zr){
x=++tot;lc[x]=lc[y];rc[x]=rc[y];ad[x]=ad[y];siz[x]=siz[y]+z*(zr-zl+);
if(zl==l&&r==zr){ad[x]+=z;return;}
LL mid=(l+r)/;
if(zr<=mid)build(lc[x],lc[y],l,mid,z,zl,zr);
else if(zl>mid) build(rc[x],rc[y],mid+,r,z,zl,zr);
else {
build(lc[x],lc[y],l,mid,z,zl,mid);
build(rc[x],rc[y],mid+,r,z,mid+,zr);
}
}
LL getsum(LL x,LL y,LL l,LL r,LL zl,LL zr){
if(zl==l&&r==zr)return siz[y]-siz[x];
LL mid=(l+r)/,ans=(ad[y]-ad[x])*(zr-zl+);
if(zr<=mid)return ans+getsum(lc[x],lc[y],l,mid,zl,zr);
else if(zl>mid) return ans+getsum(rc[x],rc[y],mid+,r,zl,zr);
else {
return ans+getsum(lc[x],lc[y],l,mid,zl,mid)+getsum(rc[x],rc[y],mid+,r,mid+,zr);
}
}
//以上主席树
inline void fir(){
LL i;
a[]=a[n+]=(<<);
for(i=;i<=n;++i){
while(a[sta[tail]]<=a[i])tail--;
lp[i]=sta[tail];sta[++tail]=i;
}
sta[]=n+;tail=;
for(i=n;i>;--i){
while(a[sta[tail]]<=a[i])tail--;
rp[i]=sta[tail];sta[++tail]=i;
}
}
inline void init(LL x,LL l,LL r,LL v){
e[++cnt].x=x;e[cnt].l=l;e[cnt].r=r;e[cnt].v=v;
}
inline void fir2(){
LL i,j;
for(i=;i<=n;++i){
if(lp[i]!=&&rp[i]!=n+)init(lp[i],rp[i],rp[i],p1);
if(i<n)init(i,i+,i+,p1);
if(lp[i]!=&&rp[i]-i>)init(lp[i],i+,rp[i]-,p2);
if(rp[i]!=n+&&i-lp[i]>)init(rp[i],lp[i]+,i-,p2);
}
sort(e+,e+cnt+,mcmp);
for(i=j=;i<=n;++i){
rt[i]=rt[i-];
for(;e[j].x==i&&j<=cnt;++j)build(rt[i],rt[i],,n,e[j].v,e[j].l,e[j].r);
}
}
int main(){
LL i,x,y,ans=;
n=read();m=read();p1=read();p2=read();
for(i=;i<=n;++i)a[i]=read();
fir(); fir2();
for(i=;i<=m;++i){
x=read();y=read();
if(x>y)swap(x,y);
ans=getsum(rt[x-],rt[y],,n,x,y);
printf("%lld\n",ans);
}
return ;
}

BZOJ 4826: [Hnoi2017]影魔 单调栈 主席树的更多相关文章

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

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

  2. [BZOJ4826] [HNOI2017] 影魔 单调栈 主席树

    题面 因为是一个排列,所以不会有重复的.如果有重复就没法做了.一开始没有仔细看题目想了半天. 发现,如果是第一种情况,那么边界\(l\)和\(r\)就应该分别是整个区间的最大值和次大值. 然后,对于那 ...

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

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

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

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

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

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

  6. ●BZOJ 4826 [Hnoi2017]影魔

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

  7. 【BZOJ4826】[Hnoi2017]影魔 单调栈+扫描线

    [BZOJ4826][Hnoi2017]影魔 Description 影魔,奈文摩尔,据说有着一个诗人的灵魂.事实上,他吞噬的诗人灵魂早已成千上万.千百年来,他收集了各式各样的灵魂,包括诗人.牧师.帝 ...

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

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

  9. BZOJ:4826: [Hnoi2017]影魔

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

随机推荐

  1. UNIX环境高级编程 第3章 文件I/O

    前面两章说明了UNIX系统体系和标准及其实现,本章具体讨论UNIX系统I/O实现,包括打开文件.读文件.写文件等. UNIX系统中的大多数文件I/O只需要用到5个函数:open.read.write. ...

  2. javaScript书写规范

    命名规范. 常量名    全部大写并单词间用下划线分隔    如:CSS_BTN_CLOSE.TXT_LOADING对象的属性或方法名    小驼峰式(little camel-case)    如: ...

  3. 2016.5.21——Compare Version Numbers

    Compare Version Numbers 本题收获: 1.字符串型数字转化为整型数字的方法:s[i] - '0',( 将字母转化为数字是[i]-'A'   ) 2.srt.at(),substr ...

  4. excel导入时候日期格式转成date

    最近在做导入的时候发现,excel中设置数值格式是不能有日期的那些符号出现的,/ - : 之类的,否则就会变成数字到了java后台,设置成日期,比如 yyyy-mm-dd 到了后台也是数字,即距离19 ...

  5. python3之pymysql模块

    1.python3 MySQL数据库链接模块 PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2中则使用mysqldb. PyMySQL 遵循 Pyt ...

  6. 洛谷P2458 保安站岗

    传送门啦 分析: 树形dp刚刚入门,这是我做的第一个一个点同时受父亲节点和儿子节点控制的题目. 由于这个题中某一个点放不放保安与父亲和儿子都有关系(因为线段的两个端点嘛),所以我们做题时就要考虑全面. ...

  7. 面试题:输入两个整数 n 和 m,从数列1,2,3…….n 中 随意取几个数, 使其和等于 m

    问题: 2010年中兴面试题 编程求解: 输入两个整数 n 和 m,从数列1,2,3…….n 中 随意取几个数, 使其和等于 m ,要求将其中所有的可能组合列出来. 思路: 类似这种组合问题一般都是使 ...

  8. Linux系统的优势

    熟悉电脑的人都知道,Linux 相比较于 Windows 有着众多的优势,所以现在越来越多的电脑用户开始使用 Linux 进行办公.学习.总体来讲,Linux 的优势主要有以下几个方面. 一.开源.免 ...

  9. hdu 4788 (2013成都现场赛 H题)

    100MB=10^5KB=10^8B 100MB=100*2^10KB=100*2^20B Sample Input2100[MB]1[B] Sample OutputCase #1: 4.63%Ca ...

  10. android拾遗——Android Intent详解

    一. Intent 作用 Intent 是一个将要执行的动作的抽象的描述,一般来说是作为参数来使用,由Intent来协助完成android各个组件之间的通讯.比如说调用startActivity()来 ...