题目:

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

HINT

Source

题解:

引用下lcf2000的题解,%%%%%%%%

我们枚举最大值的位置i,找出左边第一个比ai大的位置l,右边第一个比ai大的位置r,然后我们分开考虑一下p1和p2的贡献。

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

容易发现只有左端点为l,右端点为r才会产生p1的贡献然后产生p2贡献的有两种:一种是左端点为l,右端点在区间(i,r)中;另一种是左端点区间(l,i)中,右端点为r。

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

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

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

自己再说一两句吧···

这道题最先开始要想到的是每次考虑对答案贡献的时候首先要想到的是枚举中间的点···而不是两旁·····

其实这种考虑贡献对象的思路在很多地方都有用到···比如有时做与树有关的题很多时候我们考虑对答案贡献都是考虑每一条边·····希望下次遇到这种题能记住这种思想···

然后就是转二维平面····这个其实比较好想···毕竟看到了点对嘛···

想到转二维那么扫描线和线段树(我是用线段树写的··对带区间修改的树状数组不是太熟···)就是顺理成章的的事情了···

然而转二维时有个细节要注意····一个点可能没有左边第一个比自己大的位置l,或者没有右边第一个比自己大的位置r,如果仅仅是这二者中间少了一个···它也是会对答案产生贡献的···比如7 9 10中的9·····md因为这一点被样例卡着过不去23333

然后就是排序了···修改一定要排在询问前面当高度相同时··这点在cdq分治时其实经常提到·····一定要注意了

最后吐槽一句洛谷为毛要卡线段树啊艹···现在哪有放树状数组不放线段树的···还是bzoj不坑···

代码:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<ctime>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
using namespace std;
const int N=2e5+;
struct node
{
int x,y,h,v,id;
}q[N*];
int n,m,p1,p2,stack[N],top,num[N],Le[N],Ri[N],cnt,tag[N*];
long long ans[N],tree[N*];
inline int R()
{
char c;int f=;
for(c=getchar();c<''||c>'';c=getchar());
for(;c<=''&&c>='';c=getchar())
f=(f<<)+(f<<)+c-'';
return f;
}
inline bool cmp(node a,node b)
{
if(a.h==b.h) return a.id<b.id;
return a.h<b.h;
}
inline void add(int k,int l,int r,int v)
{
tree[k]+=(long long)(r-l+)*v;
tag[k]+=v;
}
inline void pushdown(int k,int l,int r,int mid)
{
if(tag[k])
{
add(k*,l,mid,tag[k]);
add(k*+,mid+,r,tag[k]);
tag[k]=;
}
}
inline void modify(int k,int l,int r,int x,int y,int v)
{
if(l>=x&&r<=y)
{
add(k,l,r,v);
return;
}
int mid=(l+r)/;
pushdown(k,l,r,mid);
if(x<=mid) modify(k*,l,mid,x,y,v);
if(y>mid) modify(k*+,mid+,r,x,y,v);
tree[k]=tree[k*]+tree[k*+];
}
inline long long query(int k,int l,int r,int x,int y)
{
if(l>=x&&r<=y)
return tree[k];
int mid=(l+r)/;
pushdown(k,l,r,mid);long long temp=;
if(x<=mid) temp+=query(k*,l,mid,x,y);
if(y>mid) temp+=query(k*+,mid+,r,x,y);
return temp;
}
int main()
{
//freopen("a.in","r",stdin);
n=R(),m=R(),p1=R(),p2=R();int a,b;
for(int i=;i<=n;i++) num[i]=R();
for(int i=;i<=n;i++)
{
while(top&&num[i]>num[stack[top]]) Ri[stack[top]]=i,top--;
if(top) Le[i]=stack[top];
stack[++top]=i;
}
for(int i=;i<=m;i++)
{
a=R(),b=R();ans[i]=(long long)(b-a)*p1;
q[++cnt].x=a,q[cnt].y=b,q[cnt].h=a-,q[cnt].v=-;q[cnt].id=i;
q[++cnt].x=a,q[cnt].y=b,q[cnt].h=b,q[cnt].v=;q[cnt].id=i;
}
for(int i=;i<=n;i++)
{
if(Ri[i]&&Le[i])
{
q[++cnt].x=Le[i],q[cnt].y=Le[i],q[cnt].h=Ri[i],q[cnt].v=p1;
if(Le[i]<i-) q[++cnt].x=Le[i]+,q[cnt].y=i-,q[cnt].h=Ri[i],q[cnt].v=p2;
if(Ri[i]>i+) q[++cnt].x=i+,q[cnt].y=Ri[i]-,q[cnt].h=Le[i],q[cnt].v=p2;
}
else if(Ri[i])
{
if(i>) q[++cnt].x=,q[cnt].y=i-,q[cnt].h=Ri[i],q[cnt].v=p2;
}
else if(Le[i])
{
if(i<n) q[++cnt].x=i+,q[cnt].y=n,q[cnt].h=Le[i],q[cnt].v=p2;
}
}
sort(q+,q+cnt+,cmp);
for(int i=;i<=cnt;i++)
{
if(q[i].id)
ans[q[i].id]+=(long long)q[i].v*query(,,n,q[i].x,q[i].y);
else
modify(,,n,q[i].x,q[i].y,q[i].v);
}
for(int i=;i<=m;i++)
printf("%lld\n",ans[i]);
return ;
}
 

刷题总结——影魔(HNOI2017 BZOJ4826 线段树+扫描线)的更多相关文章

  1. 刷题总结——旅馆(bzoj1593线段树)

    题目: Description 奶牛们最近的旅游计划,是到苏必利尔湖畔,享受那里的湖光山色,以及明媚的阳光.作为整个旅游的策划者和负责人,贝茜选择在湖边的一家著名的旅馆住宿.这个巨大的旅馆一共有N ( ...

  2. 洛谷P3722 影魔 [AH2017/HNOI2017] 线段树+扫描线

    正解:线段树+扫描线 解题报告: 传送门! 先理解一下这道题,大概是这样儿的: 对于一个点对,如果他们的两端是这段区间的最大值和次大值,那么他们会有p1的贡献 如果他们的两端是最大值和一个非次大值,那 ...

  3. 洛谷P3246 序列 [HNOI2016] 莫队/线段树+扫描线

    正解:莫队/线段树+扫描线 解题报告: 传送门! 似乎是有两种方法的,,,所以分别港下好了QAQ 第一种,莫队 看到这种询问很多区间之类的就会自然而然地想到莫队趴?然后仔细思考一下,发现复杂度似乎是欧 ...

  4. 【Codeforces720D】Slalom 线段树 + 扫描线 (优化DP)

    D. Slalom time limit per test:2 seconds memory limit per test:256 megabytes input:standard input out ...

  5. 【POJ-2482】Stars in your window 线段树 + 扫描线

    Stars in Your Window Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 11706   Accepted:  ...

  6. BZOJ-3225 立方体覆盖 线段树+扫描线+乱搞

    看数据范围像是个暴力,而且理论复杂度似乎可行,然后被卡了两个点...然后来了个乱搞的线段树+扫描线.. 3225: [Sdoi2008]立方体覆盖 Time Limit: 2 Sec Memory L ...

  7. hdu 5091(线段树+扫描线)

    上海邀请赛的一道题目,看比赛时很多队伍水过去了,当时还想了好久却没有发现这题有什么水题的性质,原来是道成题. 最近学习了下线段树扫描线才发现确实是挺水的一道题. hdu5091 #include &l ...

  8. POJ-1151-Atlantis(线段树+扫描线+离散化)[矩形面积并]

    题意:求矩形面积并 分析:使用线段树+扫描线...因为坐标是浮点数的,因此还需要离散化! 把矩形分成两条边,上边和下边,对横轴建树,然后从下到上扫描上去,用col表示该区间有多少个下边,sum代表该区 ...

  9. 2018牛客网暑假ACM多校训练赛(第四场)E Skyline 线段树 扫描线

    原文链接https://www.cnblogs.com/zhouzhendong/p/NowCoder-2018-Summer-Round4-E.html 题目传送门 - https://www.no ...

随机推荐

  1. Spark Job调优(Part 2)

    原文链接:https://wongxingjun.github.io/2016/05/11/Spark-Job%E8%B0%83%E4%BC%98-Part-2/ 这篇文章将会完成Part 1中留下的 ...

  2. 1066: 输入n个数和输出调整后的n个数

    1066: 输入n个数和输出调整后的n个数 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 2739  Solved: 1578[Submit][Stat ...

  3. MySql查询时间段的方法

    本文实例讲述了MySql查询时间段的方法.分享给大家供大家参考.具体方法如下: MySql查询时间段的方法未必人人都会,下面为您介绍两种MySql查询时间段的方法,供大家参考. MySql的时间字段有 ...

  4. 剑指offer题目分类

    1. 链表 1. 从尾到头打印链表 2. 链表中倒数第k个结点 3. 反转链表 4. 合并两个排序的链表 5. 复杂链表的复制 6. 复杂链表的复制 7. 两个链表的第一个公共结点 8. 链表中环的入 ...

  5. 01_4_Struts路径问题

    01_4_Struts路径问题 1. Struts路径问题说明 struts2中的路径问题是根据action的路径而不是jsp路径来确定,所有尽量不要使用相对路径. 虽然可以使用redirect方式解 ...

  6. vue 前端判断输入框不能输入0 空格。特殊符号。

    oninput="value=value.replace(/[^\d.]/g,'').replace(/\.{2,}/g,'.').replace('.','$#$').replace(/\ ...

  7. C++ 学习笔记(四)类的内存分配及this指针

    类,是使用C++的最主要的内容.如果将c++与C语言做比较,我感觉类更像是结构体的加强进化版.在刚接触C++不久的时候总是让类,对象,this指针弄得一脸懵逼,我对类有比较清楚的认识是从理解类在内存中 ...

  8. jenkins+maven+svn 自动化部署

    背景: 公司的web平台使用JAVA写的,但是不是用Tomcat部署的,代码内部自带了Web服务器,所以只需要有JAVA环境,将代码打包上传,启动脚本就可以. 项目是根据pom.xml打包成的是.zi ...

  9. LeetCode(147) Insertion Sort List

    题目 Sort a linked list using insertion sort. 分析 实现链表的插入排序 注意: 程序入口的特殊输入判断处理! 节点的链接处理,避免出现断链! AC代码 /** ...

  10. 12864点阵液晶显示模块的原理和实例程序(HJ12864M-1)

    12864点阵液晶显示模块(LCM)就是由 128*64个液晶显示点组成的一个128列*64行的阵列.每个显示点对应一位二进制数,1表示亮,0表示灭.存储这些点阵信息的RAM称为显示数据存 储器.要显 ...