参考:https://www.cnblogs.com/lcf-2000/p/6789680.html

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

枚举最大值a[i],找到l[i],r[i]是左边最后一个比它大的和右边第一个比它大的,考虑贡献:

p1:每次询问要先加上(r-l)*p1是点对相邻,然后对r[i]有p1贡献的左端点是l[i]

p2:对l[i]有贡献的是(i+1,r[i]-1),对r[i]有贡献的是(l[i]+1,i-1)

离线排序+扫描线做就行,情况都要考虑到。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=400005;
int n,m,p1,p2,a[N],s[N],top,r[N],l[N],tot;
long long ans[N],c1[N],c2[N];
struct qwe
{
int l,r,x,b,z;
qwe(int L=0,int R=0,int X=0,int B=0,int Z=0)
{
l=L,r=R,x=X,b=B,z=Z;
}
}b[N],c[N];
bool cmp(const qwe &a,const qwe &b)
{
return a.x<b.x;
}
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
int lb(int x)
{
return x&(-x);
}
void add(int x,int v)
{
if(!x)
return;
for(int i=x;i<=n;i+=lb(i))
c1[i]+=v,c2[i]+=1ll*x*v;
}
long long ques(int x)
{
long long re=0;
for(int i=x;i>0;i-=lb(i))
re+=(x+1)*c1[i]-c2[i];
return re;
}
int main()
{
n=read(),m=read(),p1=read(),p2=read();
a[0]=a[n+1]=n+1;
s[top=1]=0;
for(int i=1;i<=n+1;i++)
{
if(i<=n)
a[i]=read();
while(a[s[top]]<a[i])
r[s[top--]]=i;
l[i]=s[top];
s[++top]=i;
}
for(int i=1;i<=m;i++)
{
int l=read(),r=read();
ans[i]+=(r-l)*p1;//相邻两个点产生的贡献
b[i]=qwe(l,r,l-1,i,-1);
b[i+m]=qwe(l,r,r,i,1);
}
sort(b+1,b+1+2*m,cmp);
for(int i=1;i<=n;i++)
{
if(l[i]&&r[i]<=n)
c[++tot]=qwe(l[i],l[i],r[i],0,p1);
if(l[i]&&r[i]>i+1)
c[++tot]=qwe(i+1,r[i]-1,l[i],0,p2);
if(r[i]<=n&&i>l[i]+1)
c[++tot]=qwe(l[i]+1,i-1,r[i],0,p2);
}
sort(c+1,c+1+tot,cmp);
int w1=1,w2=1;
while(!b[w1].x)
w1++;
for(int i=1;w1<=m*2&&i<=n;i++)//扫描线
{
while(w2<=tot&&c[w2].x==i)
{
add(c[w2].r+1,-c[w2].z);
add(c[w2].l,c[w2].z);
w2++;
}
while(w1<=2*m&&b[w1].x==i)
{
ans[b[w1].b]+=b[w1].z*(ques(b[w1].r)-ques(b[w1].l-1));
w1++;
}
}
for(int i=1;i<=m;i++)
printf("%lld\n",ans[i]);
return 0;
}

bzoj 4826: [Hnoi2017]影魔【单调栈+树状数组+扫描线】的更多相关文章

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

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

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

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

  3. 牛客小白月赛13-H(单调栈+树状数组)

    题目链接:https://ac.nowcoder.com/acm/contest/549/H 题意:给一个柱状图,包括每个矩阵的宽度和高度,求能组成的最大矩阵的面积. 思路:显然最大矩阵的高一定为n个 ...

  4. Codeforces 786C Till I Collapse(树状数组+扫描线+倍增)

    [题目链接] http://codeforces.com/contest/786/problem/C [题目大意] 给出一个数列,问对于不同的k,将区间划分为几个, 每个区间出现不同元素个数不超过k时 ...

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

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

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

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

  7. BZOJ 2819: Nim dfs序维护树状数组,倍增

    1.随机选两个堆v,u,询问若在v到u间的路径上的石子堆中玩Nim游戏,是否有必胜策略,如果有,vfleaking将会考虑将这些石子堆作为初始局面之一,用来坑玩家.2.把堆v中的石子数变为k. 分析: ...

  8. BZOJ.4888.[TJOI2017]异或和(树状数组)

    BZOJ 洛谷 \(Description\) 求所有区间和的异或和. \(n\leq 10^5,\ \sum a_i\leq 10^6\). \(Solution\) 这样的题还是要先考虑按位做. ...

  9. BZOJ.4553.[HEOI2016&TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)

    题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j) if(a[ ...

随机推荐

  1. LightOJ1094 - Farthest Nodes in a Tree(树的直径)

    http://lightoj.com/volume_showproblem.php?problem=1094 Given a tree (a connected graph with no cycle ...

  2. XMLHttpRequest对象解读

    <!DOCTYPE html> <html> <body> <script> function reqListener () { console.log ...

  3. HDU 5301 Buildings(2015多校第二场)

    Buildings Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Tota ...

  4. VS code - code Snippet

    For anyone working on the UI and using VS Code, you can create a user Snippet and keyboard shortcut ...

  5. 移动APP怎样保存用户password

    <span style="font-size:14px;">为了更好的用户体验,移动APPclient一般都会将用户信息进行保存以便兴许能够自己主动登录.</sp ...

  6. (原创)EasyUI中datagrid的行编辑模式中,找到特定的Editor,并为其添加事件

    有时候在行编辑的时候,一个编辑框的值要根据其它编辑框的值进行变化,那么可以通过在开启编辑时,找到特定的Editor,为其添加事件 // 绑定事件, index为当前编辑行 var editors = ...

  7. 2016/05/06 Sublime Text 3 常用插件以及安装方法(转)

    http://www.cnsecer.com/460.html 安装Sublime Text 3插件的方法: 朋友们,小站活着不容易,全靠广告费养着了,如果本文对你有帮助.麻烦动下手点下页面的广告吧, ...

  8. 2016/3/13 MySQL 增删查改 CRUD 用代码实现

    用代码实现数据库数据输入 T-SQL语句 查询语句分几块 ①创建表 create table Car (Code varchar(50) primary key, #primary key 主键 定义 ...

  9. java8--网络编程(java疯狂讲义3复习笔记)

    重点复习一下网络通信和代理 java的网络通信很简单,服务器端通过ServerSocket建立监听,客户端通过Socket连接到指定服务器后,通信双方就可以通过IO流进行通信. 需要重点看的工具类:I ...

  10. [BZOJ2144]国家集训队 跳跳棋

    题目描述 跳跳棋是在一条数轴上进行的.棋子只能摆在整点上.每个点不能摆超过一个棋子. 我们用跳跳棋来做一个简单的游戏:棋盘上有3颗棋子,分别在a,b,c这三个位置.我们要通过最少的跳动把他们的位置移动 ...