首先用单调栈和扫描线处理出每一个数左面最近的比他大的数在$l[i]$,右面最近的比他大的数$r[i]$。

然后就可以考虑每种贡献是在什么时候产生的。

1、$(l[i],r[i])$产生$p1$的贡献

2、$([l[i]]-[i-1],i)$产生$p2$的贡献

3、$(i,[i+1]-[r[i]])$产生$p2$的贡献。

然后发现在笛卡尔坐标系中是一些线段和点,然后平行与扫描线的比较好解决。

但是垂直的就比较麻烦了。

然后有人用六棵主席树做过去了,也有人用四棵。

其实只要线段树分两次扫一遍就好了。

#include <map>
#include <ctime>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define ll long long
#define maxn 200005 struct Options{
int opt; //1 add 0 query
int x,y,z,d,id;
Options() {}
Options(int _opt,int _x,int _y,int _z,int _d)
{opt=_opt;x=_x;y=_y;z=_z;d=_d;}
void print()
{
printf("Opt %d ( %d , %d , %d ) ID %d D: %d\n",opt,x,y,z,id,d);
}
}q[maxn<<3]; int n,m,p1,p2,a[maxn],cnt=0,sta[maxn],top,l[maxn],r[maxn],_l[maxn],_r[maxn];
ll ans[maxn],sum[maxn<<3],mark[maxn<<3]; bool cmp1(Options a,Options b)
{return a.x==b.x?a.opt>b.opt:a.x<b.x;}
bool cmp2(Options a,Options b)
{return a.y==b.y?a.opt>b.opt:a.y<b.y;} void update(int o)
{sum[o]=sum[o<<1]+sum[o<<1|1];} void pushdown(int o,int l,int r)
{
if (mark[o]!=0)
{
int mid=l+r>>1;
sum[o<<1]+=(mid-l+1)*mark[o];
sum[o<<1|1]+=(r-mid)*mark[o];
mark[o<<1]+=mark[o];
mark[o<<1|1]+=mark[o];
mark[o]=0;
}
} void modify(int o,int l,int r,int L,int R,int f)
{
if (L<=l&&r<=R)
{
mark[o]+=f;
sum[o]+=(r-l+1)*f;
return;
}
int mid=l+r>>1;pushdown(o,l,r);
if (L<=mid) modify(o<<1,l,mid,L,R,f);
if (R>mid) modify(o<<1|1,mid+1,r,L,R,f);
update(o);
} ll query(int o,int l,int r,int L,int R)
{
if (L<=l&&r<=R) return sum[o];
int mid=l+r>>1;pushdown(o,l,r);
if (R<=mid) return query(o<<1,l,mid,L,R);
if (L>mid) return query(o<<1|1,mid+1,r,L,R);
return query(o<<1,l,mid,L,R)+query(o<<1|1,mid+1,r,L,R);
} int main()
{
scanf("%d%d%d%d",&n,&m,&p1,&p2);
F(i,1,n) scanf("%d",&a[i]);
F(i,1,m)
{
int x,y; scanf("%d%d",&_l[i],&_r[i]); x=_l[i];y=_r[i];
q[++cnt].id=i;q[cnt].d=1; q[cnt].x=y+1;q[cnt].y=y+1;q[cnt].opt=0;
q[++cnt].id=i;q[cnt].d=1; q[cnt].x=x; q[cnt].y=x; q[cnt].opt=0;
q[++cnt].id=i;q[cnt].d=-1;q[cnt].x=x; q[cnt].y=y+1;q[cnt].opt=0;
q[++cnt].id=i;q[cnt].d=-1;q[cnt].x=y+1;q[cnt].y=x; q[cnt].opt=0;
}
F(i,1,n)
{
while(top&&a[sta[top]]<a[i]) top--;
l[i]=sta[top];
sta[++top]=i;
}
sta[top=0]=n+1;
D(i,n,1)
{
while(top&&a[sta[top]]<a[i]) top--;
r[i]=sta[top];
sta[++top]=i;
}
F(i,1,n-1)
{
q[++cnt].opt=1;q[cnt].x=i+1;q[cnt].y=i+2;q[cnt].z=i+2;q[cnt].d=p1;
}
F(i,1,n)
{
q[++cnt]=Options(1,l[i]+1,r[i]+1,r[i]+1,p1);
if (r[i]-1>=i+1) q[++cnt]=Options(1,l[i]+1,i+2,r[i],p2);
}
sort(q+1,q+cnt+1,cmp1);
F(i,1,cnt)
{
switch(q[i].opt)
{
case 0:ans[q[i].id]+=q[i].d*query(1,1,n+2,1,q[i].y);break;
case 1:modify(1,1,n+2,q[i].y,q[i].z,q[i].d);break;
}
}
memset(sum,0,sizeof sum); memset(mark,0,sizeof mark);cnt=0;
F(i,1,m)
{
int x,y;x=_l[i];y=_r[i];
q[++cnt].id=i;q[cnt].d=1; q[cnt].x=y+1;q[cnt].y=y+1;q[cnt].opt=0;
q[++cnt].id=i;q[cnt].d=1; q[cnt].x=x; q[cnt].y=x; q[cnt].opt=0;
q[++cnt].id=i;q[cnt].d=-1;q[cnt].x=x; q[cnt].y=y+1;q[cnt].opt=0;
q[++cnt].id=i;q[cnt].d=-1;q[cnt].x=y+1;q[cnt].y=x; q[cnt].opt=0;
}
F(i,1,n) if (l[i]+1<=i-1) q[++cnt]=Options(1,l[i]+2,r[i]+1,i,p2);
sort(q+1,q+cnt+1,cmp2);
F(i,1,cnt)
{
switch(q[i].opt)
{
case 0:ans[q[i].id]+=q[i].d*query(1,1,n+2,1,q[i].x);break;
case 1:modify(1,1,n+2,q[i].x,q[i].z,q[i].d);break;
}
}
F(i,1,m) printf("%lld\n",ans[i]);
}

  

BZOJ 4826 [Hnoi2017]影魔 ——扫描线 单调栈的更多相关文章

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

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

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

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

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

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

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

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

  5. P3722 [AH2017/HNOI2017]影魔(单调栈+扫描线+线段树)

    题面传送门 首先我们把这两个贡献翻译成人话: 区间 \([l,r]\) 产生 \(p_1\) 的贡献当且仅当 \(a_l,a_r\) 分别为区间 \([l,r]\) 的最大值和次大值. 区间 \([l ...

  6. [bzoj4826][Hnoi2017]影魔_单调栈_主席树

    影魔 bzoj-4826 Hnoi-2017 题目大意:给定一个$n$个数的序列$a$,求满足一下情况的点对个数: 注释:$1\le n,m\le 2\cdot 10^5$,$1\le p1,p2\l ...

  7. ●BZOJ 4826 [Hnoi2017]影魔

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

  8. BZOJ:4826: [Hnoi2017]影魔

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

  9. 4826: [Hnoi2017]影魔

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

随机推荐

  1. 2018.5.22 Oracle安装配置在虚拟机中外部电脑连接服务

    1.拷贝老师的集成文件(win系统和oracle服务) 2.安装虚拟机,并且打开镜像文件 3.启动监听程序(实例服务[自动].监听服务) 4.查看虚拟机ip,此ip要主机ip在同一个网段 5.检查虚拟 ...

  2. PAT (Basic Level) Practise (中文)- 1001. 害死人不偿命的(3n+1)猜想 (15)

    http://www.patest.cn/contests/pat-b-practise/1001 卡拉兹(Callatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那 ...

  3. windows下sorl安装

    1. JDK要求 Solr 4.10 要求JDK版本必须是1.7或更高. 2. 下载 下载地址: http://www.apache.org/dyn/closer.cgi/lucene/solr/ 下 ...

  4. 从指定的view中截图 返回UIImage

    -(UIImage *)getImageFromView:(UIView *)view{ UIGraphicsBeginImageContext(view.bounds.size); [view.la ...

  5. Sum All Odd Fibonacci Numbers-freecodecamp算法题目

    Sum All Odd Fibonacci Numbers 1.要求 给一个正整数num,返回小于或等于num的斐波纳契奇数之和. 斐波纳契数列中的前几个数字是 1.1.2.3.5 和 8,随后的每一 ...

  6. 【前端_js】前端跨网络异步获取资源——fetch()

    Fetch API 提供了一个 JavaScript接口,用于访问和操纵HTTP管道的部分,例如请求和响应.它还提供了一个全局 fetch()方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源 ...

  7. shell的条件判断

    .字符串判断 str1 = str2 当两个串有相同内容.长度时为真 str1 != str2 当串str1和str2不等时为真 -n str1 当串的长度大于0时为真(串非空) -z str1 当串 ...

  8. thinkphp 分页的 实现 和样式 分享

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAgoAAABlCAIAAACjnlykAAAI8UlEQVR4nO3bP2/bSBrH8eSQ5rq0eh ...

  9. Scrapy用pipelines把字典保存为csv格式

    import csv class MyProjectPipeline(object): # 保存为csv格式 def __init__(self): # 打开文件,指定方式为写,利用第3个参数把csv ...

  10. 大数运算:HDU-1042-N!(附N!位数的计算)

    解题心得: 这里使用了10000进制.很明显,因为是n!所以单个最大的数是10000*10000,使用万进制. 可以借鉴高精度的加法,单个乘了之后在进位. 很坑的一点,0!=1,数学不好WA了三次,尴 ...