4540: [Hnoi2016]序列

题意:询问区间所有子串的最小值的和


不强制在线当然上莫队啦

但是没想出来,因为不知道该维护当前区间的什么信息,维护前后缀最小值的话不好做

想到单调栈求一下,但是对于\([l,r]\)还是可能有很多最小值,数据不随机的话会被卡

预处理!!!

预处理\(l_i,\ r_i\)以i为最小值的范围,\(fl[i],\ fr[i]\)为从i开始 / 以i结尾的的前缀 / 后缀 最小值的和

\(fr[i] = (i - l_i + 1) * a_i + fr[i] - fr[l_i - 1]\)

这是可减的!!!

\([l, r] \rightarrow [l, r+1]\),求出\(p=rmq(l, r+1)\),对于\(p-l+1\)这些后缀最小值就是\(a_p\),剩下的直接用预处理的信息就行了 \(fr[r] - fr[p]\)

遇到不好处理的情况一定要想一下预处理 / DP

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=1e5+5;
inline ll read() {
char c=getchar(); ll x=0,f=1;
while(c<'0' || c>'9') {if(c=='-')f=-1; c=getchar();}
while(c>='0' && c<='9') {x=x*10+c-'0'; c=getchar();}
return x*f;
} int n, a[N], Q, l, r, block, pos[N]; ll ans[N];
struct meow{
int l, r, id;
bool operator <(const meow &a) const {return pos[l] == pos[a.l] ? r < a.r : pos[l] < pos[a.l];}
} q[N]; namespace cat {
int l[N], r[N], st[N], top; ll fl[N], fr[N];
int f[N][18], log[N];
inline int min(int x, int y) {return a[x]<a[y] ? x : y;} void init() {
for(int i=1; i<=n; i++) {
while(top && a[ st[top] ] > a[i]) r[ st[top] ] = i-1, top--;
l[i] = st[top]+1;
st[++top] = i;
}
while(top) r[ st[top--] ] = n;
//for(int i=1; i<=n; i++) printf("%d [%d, %d]\n", i, l[i], r[i]);
for(int i=1; i<=n; i++) fr[i] = (ll) (i - l[i] + 1) * a[i] + fr[l[i] - 1];
for(int i=n; i>=1; i--) fl[i] = (ll) (r[i] - i + 1) * a[i] + fl[r[i] + 1];// printf("fl %d %lld\n",i,fl[i]); ; for(int i=1; i<=n; i++) f[i][0] = i;
for(int j=1; j<=16; j++)
for(int i=1; i+(1<<j)-1 <= n; i++)
f[i][j] = min(f[i][j-1], f[i+(1<<(j-1))][j-1]);// printf("f %d %d %d\n", i, j, f[i][j]);
log[1]=0; for(int i=2; i<=n; i++) log[i] = log[i>>1]+1;
}
inline int rmq(int l, int r) {
int t = log[r-l+1];
return min(f[l][t], f[r-(1<<t)+1][t]);
} ll now;
inline void addr(int l, int r, ll flag) {
int p = rmq(l, r);
now += flag * ( (ll) (p-l+1) * a[p] + fr[r] - fr[p] );
}
inline void addl(int l, int r, ll flag) {
int p = rmq(l, r);
now += flag * ( (ll) (r-p+1) * a[p] + fl[l] - fl[p] );
} void modui() {
sort(q+1, q+1+Q);
int l=1, r=0;
for(int i=1; i<=Q; i++) {
while(r < q[i].r) cat::addr(l, ++r, 1);
while(r > q[i].r) cat::addr(l, r--, -1);
while(l < q[i].l) cat::addl(l++, r, -1);
while(l > q[i].l) cat::addl(--l, r, 1);
ans[ q[i].id ] = now;
}
}
} int main() {
freopen("in", "r", stdin);
n=read(); Q=read(); block = sqrt(n);
for(int i=1; i<=n; i++) a[i]=read(), pos[i] = (i-1)/block+1;
for(int i=1; i<=Q; i++) l=read(), r=read(), q[i] = (meow){l, r, i};
cat::init();
cat::modui();
for(int i=1; i<=Q; i++) printf("%lld\n", ans[i]);
}

BZOj 4540: [Hnoi2016]序列 [莫队 st表 预处理]的更多相关文章

  1. BZOJ.4540.[HNOI2016]序列(莫队/前缀和/线段树 单调栈 RMQ)

    BZOJ 洛谷 ST表的一二维顺序一定要改过来. 改了就rank1了哈哈哈哈.自带小常数没办法. \(Description\) 给定长为\(n\)的序列\(A_i\).\(q\)次询问,每次给定\( ...

  2. BZOJ 4540 [Hnoi2016]序列 | 莫队 详细题解

    传送门 BZOJ 4540 题解 --怎么说呢--本来想写线段树+矩阵乘法的-- --但是嘛--yali的机房太热了--困--写不出来-- 于是弃疗,写起了莫队.(但是我连莫队都想不出来!) 首先用单 ...

  3. bzoj 4540: [Hnoi2016]序列 莫队

    题目: 给定长度为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[s:t]是a ...

  4. [HNOI2016]序列(莫队,RMQ)

    [HNOI2016]序列(莫队,RMQ) 洛谷  bzoj 一眼看不出来怎么用数据结构维护 然后还没修改 所以考虑莫队 以$(l,r-1) -> (l,r)$为例 对答案的贡献是$\Sigma_ ...

  5. [Bzoj4540][Hnoi2016] 序列(莫队 + ST表 + 单调队列)

    4540: [Hnoi2016]序列 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1567  Solved: 718[Submit][Status] ...

  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. [BZOJ4540][HNOI2016]序列 莫队

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

  8. BZOJ 4540 [Hnoi2016]序列 (单调栈 + ST表 + 莫队算法)

    题目链接  BZOJ4540 考虑莫队算法. 这题难在$[l, r]$到$[l, r+1]$的转移. 根据莫队算法的原理,这个时候答案应该加上 $cal(l, r+1) + cal(l+1, r+1) ...

  9. BZOJ4540 [Hnoi2016]序列 【莫队 + ST表 + 单调栈】

    题目 给定长度为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[s:t]是a[ ...

随机推荐

  1. The Blocks Problem(vector)

    题目链接:http://poj.org/problem?id=1208 The Blocks Problem Time Limit: 1000MS   Memory Limit: 10000K Tot ...

  2. c++(线性堆栈)

    前面我们讲到了队列,今天我们接着讨论另外一种数据结构:堆栈.堆栈几乎是程序设计的命脉,没有堆栈就没有函数调用,当然也就没有软件设计.那么堆栈有什么特殊的属性呢?其实,堆栈的属性主要表现在下面两个方面: ...

  3. Linux-vmware tools安装与cdrom挂载(转)

    昨天想直接复制虚拟机centos系统中命令行的内容到主机的txt文档上进行保存,发现不能实现虚拟机与主机之间的直接通讯,后来查资料发现原来是由于我的虚拟机没有安装vwmare tools的缘故. 一个 ...

  4. Linux下C++/C的编译调试

    这几天因为任务的原因我需要在ubuntu下编写程序.因此恶补了许多linux程序编写的知识.我分以下几个方面总结我所学的知识. gcc,g++,make命令的使用 gdb 调试 VScode的使用 c ...

  5. md5加密以及可逆的加密解密算法

    md5加密 package gov.mof.fasp2.gcfr.adjustoffset.adjust; import java.security.MessageDigest; public cla ...

  6. javascript数据类型之Array类型

    Array类型 除了Object之外,Array类型恐怕是ECMAScript中最常用的类型了.而且,ECMAScript中的数组与其他多数语言中的数组有着相当大的区别.虽然ECMAScript数组与 ...

  7. 从零开始学习前端开发 — 7、CSS宽高自适应

    一.宽度自适应 语法:width:100%; 注: a)块状元素的默认宽度为100% b) 当给元素设置宽度为100%时,继承父元素的宽度 c) 通常使用宽度自适应实现通栏效果 二.高度自适应 语法: ...

  8. 怎么知道我的laravel 是几版本的

    方法1: 使用php artisan --version ,只要能看懂这个命令的人一定已经具有初步的Laravel知识. 再介绍一种不需要命令,直接去文件中去查看的方法. 方法2: 在项目文件中找ve ...

  9. linux下卸载apache方法小结

    方法一 代码如下: 1. root@server ~]# rpm -qa|grep httpd  httpd-2.2.3-11.el5_2.centos.4  httpd-manual-2.2.3-1 ...

  10. php-cli和php-fpm的关系是什么?

    CLI是命令行版本.FPM是作为Apache或者Nginx等服务器软件处理PHP文件的扩展. PHP的默认版本是不支持线程安全的,这个线程安全问题可以去了解PHP扩展开发方面的相关知识,这是因为C语言 ...