莫队+st表

据说这是经典问题,但是我不会。。。

问题在于莫队怎么算贡献,每次移动一个位置,现在为[l,r],那么就增加了[l-1,r),r的贡献,怎么算呢?我们预处理fl,fr,fl[i]表示以i为开头的前缀和,fr表示以i为结尾的后缀和,这个东西能够相减,但也不是完全满足

每次我们计算贡献的时候,设最小值的位置为p,那么对于右端点来说,贡献就是fr[r]-fr[p]+(p - l + 1) * a[p],这也是因为不完全满足可减性,因为求前缀和是fr[i]=(i - l[i] + 1) * a[i] + fr[l[i]-1],那么满足可减性是在每个l[i]的时候可以减,又因为p作为最小值肯定是处于一个l的位置,那么就能减了,而到l的贡献就是p作为最小值。

理解得还不是很透彻 我一直以为我的单调栈是左闭右闭的,竟然是左开右闭的

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + ;
int n, m, block, l = , r, top;
ll sum;
int st[N], Log[N], f[N][], L[N], R[N];
ll fl[N], fr[N], a[N], ans[N];
struct query {
int l, r, id;
bool friend operator < (const query &a, const query &b) {
return (a.l - ) / block == (b.l - ) / block ? a.r < b.r : (a.l - ) / block < (b.l - ) / block;
}
} q[N];
inline int rd()
{
int x = , f = ; char c = getchar();
while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
while(c >= '' && c <= '') { x = x * + c - ''; c = getchar(); }
return x * f;
}
int Min(int x, int y)
{
return a[x] < a[y] ? x : y;
}
int rmq(int l, int r)
{
int x = Log[r - l + ];
return Min(f[l][x], f[r - ( << x) + ][x]);
}
void addl(int l, int r, ll f)
{
int p = rmq(l, r);
sum += f * (fl[l] - fl[p] + a[p] * (ll)(r - p + ));
}
void addr(int l, int r, ll f)
{
int p = rmq(l, r);
sum += f * (fr[r] - fr[p] + a[p] * (ll)(p - l + ));
}
int main()
{
n = rd();
m = rd();
block = sqrt(n);
for(int i = ; i <= n; ++i)
{
a[i] = rd();
f[i][] = i;
}
for(int i = ; i <= n; ++i) Log[i] = Log[i >> ] + ;
for(int j = ; j <= ; ++j)
for(int i = ; i + ( << j) <= n + ; ++i)
f[i][j] = Min(f[i][j - ], f[i + ( << (j - ))][j - ]);
for(int i = ; i <= m; ++i)
{
q[i].l = rd();
q[i].r = rd();
q[i].id = i;
}
sort(q + , q + m + );
for(int i = ; i <= n; ++i)
{
L[i] = R[i] = i;
while(top && a[st[top]] > a[i])
{
R[st[top - ]] = R[st[top]];
L[i] = L[st[top]];
--top;
}
st[++top] = i;
}
while(top)
{
R[st[top - ]] = R[st[top]];
--top;
}
for(int i = ; i <= n; ++i) fr[i] = fr[L[i] - ] + (ll)(i - L[i] + ) * a[i];
for(int i = n; i; --i) fl[i] = fl[R[i] + ] + (ll)(R[i] - i + ) * a[i];
l = ;
r = ;
for(int i = ; i <= m; ++i)
{
while(r < q[i].r) addr(l, ++r, );
while(r > q[i].r) addr(l, r--, -);
while(l < q[i].l) addl(l++, r, -);
while(l > q[i].l) addl(--l, r, );
ans[q[i].id] = sum;
}
for(int i = ; i <= m; ++i) printf("%lld\n", ans[i]);
return ;
}

莫队一定要先动r

bzoj4540的更多相关文章

  1. 【bzoj4540】 Hnoi2016—序列

    http://www.lydsy.com/JudgeOnline/problem.php?id=4540 (题目链接) 题意 给出$n$个数的序列,$m$个询问,每次询问一段区间$[l,r]$,问$[ ...

  2. 【BZOJ4540】【HNOI2016】序列(莫队)

    [BZOJ4540][HNOI2016]序列(莫队) 题面 BZOJ 洛谷 Description 给定长度为n的序列:a1,a2,-,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是 ...

  3. BZOJ4540 Hnoi2016 序列 【莫队+RMQ+单调栈预处理】*

    BZOJ4540 Hnoi2016 序列 Description 给定长度为n的序列:a1,a2,-,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,-,ar- ...

  4. 【BZOJ4540】[Hnoi2016]序列 莫队算法+单调栈

    [BZOJ4540][Hnoi2016]序列 Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,a ...

  5. BZOJ4540 [Hnoi2016]序列

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  6. [bzoj4540][Hnoi2016][序列] (莫队算法+单调栈+st表)

    Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,ar-1,ar.若1≤l≤s≤t≤r≤n,则称a ...

  7. [luogu3246][bzoj4540][HNOI2016]序列【莫队+单调栈】

    题目描述 给定长度为n的序列:a1,a2,...,an,记为a[1:n].类似地,a[l:r](1<=l<=r<=N)是指序列:al,al+1,...,ar-1,ar.若1<= ...

  8. bzoj4540 序列 (单调栈+莫队+rmq)

    首先,如果我知道[l,r],要转移到[l,r+1]的时候,就是加上以r+1为右端点,[l,r+1]为左端点的区间的最小值,其他情况和这个类似 考虑这玩意怎么求 右端点固定的话,我左端点越往左走,这个最 ...

  9. [BZOJ4540][HNOI2016]序列 莫队

    4540: [Hnoi2016]序列 Time Limit: 20 Sec  Memory Limit: 512 MB Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n ...

  10. 【bzoj4540】[Hnoi2016]序列 单调栈+离线+扫描线+树状数组区间修改区间查询

    题目描述 给出一个序列,多次询问一个区间的所有子区间最小值之和. 输入 输入文件的第一行包含两个整数n和q,分别代表序列长度和询问数.接下来一行,包含n个整数,以空格隔开,第i个整数为ai,即序列第i ...

随机推荐

  1. ffmpeg h264编码 extradata 为空

    ffmpeg h264编码的例子前面的文章已经介绍,本来主要讲述影响AVCodecContext extradata是否为 空的配置项.如果要求open编码器以后AVCodecContext extr ...

  2. 3D打印技术之切片引擎(4)

    [此系列文章基于熔融沉积( fused depostion modeling, FDM )成形工艺] 这一篇文章我讲一下多边打印的问题,多边打印是切片引擎的一项关键的技术. 图1 双边打印 首先.它能 ...

  3. iOS设计模式 - (2)UML类间关系精解

    在正式讲设计模式之前, 介绍一下UML类图之间的关系还是非常有必要的, 由于一些教程, 书籍, 包含我之后的文章, 都会大量使用类图, 去描写叙述各个类之间的关系.这是一种非常直观, 简约的方式. 当 ...

  4. Linaro/Yocto/Openwrt

    http://en.wikipedia.org/wiki/Linaro Linaro From Wikipedia, the free encyclopedia     This article ap ...

  5. 【leetcode】Jump Game I, II 跳跃游戏一和二

    题目: Jump Game I: Given an array of non-negative integers, you are initially positioned at the first ...

  6. sql server t-sql脚本转成oracle plsql

    将一份SQL SERVER数据库生成的T-SQL脚本,转成ORACLE的PL/SQL,其复杂繁琐程度,远远出乎我的意料. 这份SQL SERVER脚本,里面有表,有视图,还有存储过程,以及一些自定义函 ...

  7. 远程访问Linux的常见方式

    访问方式 不加密文字界面:telnet.rsh 加密文字界面:SSH 图形界面:Xdmcp.RDP.VNC SSH SSH用来取代finger.R shell(rlogin.rcp.rsh).teln ...

  8. IP address could not be resolved: Name or service not known

    [root@test ~]# /usr/local/mysql/bin/mysqld2018-08-05T07:00:33.647509Z 0 [Warning] [MY-011070] [Serve ...

  9. Redisson实现Redis分布式锁的N种姿势(转)

    Redis几种架构 Redis发展到现在,几种常见的部署架构有: 单机模式: 主从模式: 哨兵模式: 集群模式: 我们首先基于这些架构讲解Redisson普通分布式锁实现,需要注意的是,只有充分了解普 ...

  10. css定位的元素内层不自动扩高解决

        给最外层的CSS加上一行: 1 position: relative;             /* 给最外层加上这行 */