题目:

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. 三、npm start报错:./node_modules/history/esm/history.js解决办法

    package.json中的roadhog换为:'^2.5.0-beta.4',删除node_modules文件夹,在执行npm install,npm start.

  2. python_98_面向对象_学校

    class School(object):#以后都加object(基类) def __init__(self, name, addr): self.name = name self.addr = ad ...

  3. win7便笺元数据损坏,最新解决办法

    Windows7系统开机时出现“部分便笺的元数据已被破坏,便笺已将其恢复为默认值.”问题,最新解决办法,图文说明,亲测,希望可以帮到大家 工具/原料   Windows7系统 InkObj.dll.T ...

  4. OO第三次电梯作业优化

    目录 第三次电梯作业个人优化 前言 优化思路 一.调度器 二.电梯 第三次电梯作业个人优化 前言 由于个人能力有限,第二次电梯作业只能完成正确性设计,没能进行优化,也因此损失了强测分数,于是第三次电梯 ...

  5. Linux安装项目管理工具禅道出现的一些问题

    我这边是直接使用的lamp一键安装的环境 lamp地址如下:https://lnmp.org/ 然后直接下载禅道源码解压后放入/home/wwwroot/default此目录下 然后访问禅道源码里面的 ...

  6. 学习笔记(二):使用 TensorFlow 的起始步骤(First Steps with TensorFlow)

    目录 1.工具包 TensorFlow 张量 (Tensor) 图 (graph) TensorBoard 2.tf.estimator API Estimator 预创建的 Estimator (p ...

  7. numpy学习(一)

    numpy数据类型 # numpy创建对象,numpy创建的对象是n阶矩阵,类似python中列表的嵌套 nd = np.array([[1,2,3,4,5],[2,3,4,6,5]])nd 结果: ...

  8. java的一些相关介绍(2013-10-07-163 写的日志迁移

    java是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台(即JavaSE, JavaEE, Jav ...

  9. jQuery获取动态添加的元素,live和on的区别

    今天给大家说一下如果用jQuery获取动态添加的元素,通常如果你在网页上利用jQuery添加一个元素,那么用平常的jQuery获取元素的方法无效的获取不到的.可以用以下的方法获取动态元素!假设我们现在 ...

  10. 妹子图爬取__RE__BS4

    妹子图爬取 页面链接 感谢崔大佬: 原文链接 正则实现代码: import requests import re import os import random class mzitu(): def ...