『序列 莫队 dp预处理』
<更新提示>
<第一次更新>
<正文>
序列
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[s:t]是a[l:r]的子序列。
现在有q个询问,每个询问给定两个数l和r,1≤l≤r≤n,求a[l:r]的不同子序列的最小值之和。
例如,给定序列5,2,4,1,3,询问给定的两个数为1和3,那么a[1:3]有6个子序列a[1:1],a[2:2],a[3:3],a[1:2],a[2:3],a[1:3],这6个子序列的最小值之和为5+2+4+2+2+2=17。
Input Format
输入文件的第一行包含两个整数n和q,分别代表序列长度和询问数。
接下来一行,包含n个整数,以空格隔开,第i个整数为ai,即序列第i个元素的值。
接下来q行,每行包含两个整数l和r,代表一次询问。
Output Format
对于每次询问,输出一行,代表询问的答案。
Sample Input
5 5
5 2 4 1 3
1 5
1 3
2 4
3 5
2 5
Sample Output
28
17
11
11
17
解析
回答若干个静态的区间询问,思路是莫队。
假设我们已经得到了区间\([l,r]\)的答案,直接考虑如何转移到\([l,r+1]\)。显然,我们只需要考虑包含\(r+1\)这一个点的子序列\([l,r+1],[l+1,r+1],...,[r+1,r+1]\)即可。要求的是最小值之和,我们就设\([l,r+1]\)在\(a\)序列上的区间最小值为\(a_p\),位置是\(p\),那么所有左端点在\([l,p]\)之间的区间的答案就都是\(a_p\),总共的贡献为\(a_p*(p-l+1)\),这个问题显然可以用\(ST\)表解决。
那么剩下的那些区间我们考虑用\(dp\)来计算答案。设\(f[i][j]\)代表右端点为\(j\),左端点在\([i,j]\)之间的答案之和,那么我们要求的就是\(f[p+1][r+1]\)。记录下\(prep_i\)代表\(a\)序列中\(a_i\)左边第一个比他小的元素的位置(单调栈解决),状态转移方程就是:$$f[i][j]=f[i][prep_j]+a_j*(j-prep_j)$$。
发现状态转移方程与\(i\)无关,直接将第一维舍去,那么\(f[j]\)的定义就是右端点为\(j\)的所有区间的答案之和。继续考虑原问题,发现必然存在一个点\(x\)满足\(prep_x=p\),\(f[r+1]=a_{r+1}*(r+1-prep_{r+1})+...+a_x*(x-p)+f[p]\),那么我们原来要求的\(f[p+1][r+1]\)其实可以表示为\(f[r+1]-f[p]\),然后预处理出\(f\)数组,就可在莫队当中\(O(1)\)转移了。
当然,我们还需要处理出反方向的\(f\)数组,以便莫队向左转移。如果是删除操作的话,就减去加入这个点的时候带来的贡献即可。
\(Code:\)
#include <bits/stdc++.h>
using namespace std;
const int N = 100200 , MaxlogN = 25 , INF = 2e9;
int n,m,a[N],size;
int Min[N][MaxlogN],Log2[N],Pow2[MaxlogN];
int prep[N],next[N],Stack[N],top;
long long ans[N],fl[N],fr[N],tot;
struct Query{int l,r,id;}q[N];
inline void init(void)
{
Pow2[0] = 1 , a[0] = a[n+1] = INF;
for (int i=1;i<=MaxlogN-2;i++)
Pow2[i] = Pow2[i-1] << 1;
for (int i=2;i<=n;i++)
Log2[i] = Log2[i>>1] + 1;
for (int i=1;i<=n;i++)
Min[i][0] = i;
for (int k=1;k<=Log2[n];k++)
for (int i=1;i+Pow2[k-1]-1<=n;i++)
if ( a[ Min[i][k-1] ] < a[ Min[i+Pow2[k-1]][k-1] ] )
Min[i][k] = Min[i][k-1];
else Min[i][k] = Min[i+Pow2[k-1]][k-1];
top = 0;
for (int i=1;i<=n;i++)
{
while ( top && a[Stack[top]] > a[i] )
next[ Stack[top--] ] = i;
prep[i] = Stack[top] ; Stack[++top] = i;
}
while ( top )
{
prep[ Stack[top] ] = Stack[top-1];
next[ Stack[top] ] = n+1;
top--;
}
}
inline int query(int l,int r)
{
int k = Log2[r-l+1];
if ( a[ Min[l][k] ] < a[ Min[r-Pow2[k]+1][k] ] )
return Min[l][k];
else return Min[r-Pow2[k]+1][k];
}
inline void input(void)
{
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&a[i]);
for (int i=1;i<=m;i++)
scanf("%d%d",&q[i].l,&q[i].r) , q[i].id = i;
}
inline void dp(void)
{
for (int i=1;i<=n;i++)
fr[i] = fr[prep[i]] + 1LL * a[i] * (i-prep[i]);
for (int i=n;i>=1;i--)
fl[i] = fl[next[i]] + 1LL * a[i] * (next[i]-i);
}
inline bool compare(Query p1,Query p2)
{
if ( (p1.l/size) ^ (p2.l/size) )
return p1.l < p2.l ;
else if ( (p1.l/size) & 1 )
return p1.r < p2.r ;
else return p1.r > p2.r ;
}
inline void insert1(int l,int r)
{
int p = query(l,r);
tot += ( 1LL * a[p] * (p-l+1) + fr[r] - fr[p] );
}
inline void insert2(int l,int r)
{
int p = query(l,r);
tot += ( 1LL * a[p] * (r-p+1) + fl[l] - fl[p] );
}
inline void remove1(int l,int r)
{
int p = query(l,r);
tot -= ( 1LL * a[p] * (p-l+1) + fr[r] - fr[p] );
}
inline void remove2(int l,int r)
{
int p = query(l,r);
tot -= ( 1LL * a[p] * (r-p+1) + fl[l] - fl[p] );
}
inline void CaptainMo(void)
{
double val = sqrt(1.0*m*2/3);
if ( val > n || val < 500 ) size = sqrt(n);
else size = n * 1.0 / val;
sort( q+1 , q+m+1 , compare );
int l = 1 , r = 0;
for (int i=1;i<=m;i++)
{
int ql = q[i].l , qr = q[i].r;
while ( l > ql ) insert2(--l,r);
while ( r < qr ) insert1(l,++r);
while ( l < ql ) remove2(l++,r);
while ( r > qr ) remove1(l,r--);
ans[ q[i].id ] = tot;
}
}
int main(void)
{
input();
init();
dp();
CaptainMo();
for (int i=1;i<=m;i++)
printf("%lld\n",ans[i]);
return 0;
}
<后记>
『序列 莫队 dp预处理』的更多相关文章
- 学习笔记——不带修序列莫队 (luogu2079)小B的询问
莫队是一种对于询问的离线算法 时间复杂度:O(\(n \sqrt n\)) 大致思想就是 首先将询问离线,然后对原序列分块,使得每一个\(l和r\)都在一个块里 然后按照左节点排序,若所在的块相等,就 ...
- [HNOI2016]序列(莫队,RMQ)
[HNOI2016]序列(莫队,RMQ) 洛谷 bzoj 一眼看不出来怎么用数据结构维护 然后还没修改 所以考虑莫队 以$(l,r-1) -> (l,r)$为例 对答案的贡献是$\Sigma_ ...
- BZOj 4540: [Hnoi2016]序列 [莫队 st表 预处理]
4540: [Hnoi2016]序列 题意:询问区间所有子串的最小值的和 不强制在线当然上莫队啦 但是没想出来,因为不知道该维护当前区间的什么信息,维护前后缀最小值的话不好做 想到单调栈求一下,但是对 ...
- [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 ...
- BZOJ.4540.[HNOI2016]序列(莫队/前缀和/线段树 单调栈 RMQ)
BZOJ 洛谷 ST表的一二维顺序一定要改过来. 改了就rank1了哈哈哈哈.自带小常数没办法. \(Description\) 给定长为\(n\)的序列\(A_i\).\(q\)次询问,每次给定\( ...
- bzoj 4540 [HNOI 2016] 序列 - 莫队算法 - Sparse-Table - 单调栈
题目传送门 传送点I 传送点II 题目大意 给定一个长度为$n$的序列.询问区间$[l, r]$的所有不同的子序列的最小值的和. 这里的子序列是连续的.两个子序列不同当且仅当它们的左端点或右端点不同. ...
- 【BZOJ4540】[Hnoi2016]序列 莫队算法+单调栈
[BZOJ4540][Hnoi2016]序列 Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,a ...
- 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 ...
- Bzoj 3809: Gty的二逼妹子序列 莫队,分块
3809: Gty的二逼妹子序列 Time Limit: 35 Sec Memory Limit: 28 MBSubmit: 868 Solved: 234[Submit][Status][Dis ...
随机推荐
- Java数据类型(1)
基本数据类型 A.整型 byte:(8位--1个字节 有符号 以二进制补码表示) 范围:-27~27-1 即 -128~127 short:(16位--2个字节 有符号 以二进制补码表示) 范围:-2 ...
- <人人都懂设计模式>-状态模式
同样是水,固态,气态,液态的变化,是由温度引起. 引此为思考状态模式. from abc import ABCMeta, abstractmethod # 引入ABCMeta和abstractmeth ...
- min25筛学习总结
前言 杜教筛学了,顺便把min25筛也学了吧= =刚好多校也有一道题需要补. 下面推荐几篇博客,我之后写一点自己的理解就是了. 传送门1 传送门2 传送门3 这几篇写得都还是挺好的,接下来我就写下自己 ...
- V4L2 API详解 Buffer的准备和数据读取
1. 初始化 Memory Mapping 或 User Pointer I/O. int ioctl(int fd, int requestbuf, struct v4l2_requestbuffe ...
- Nginx对图片进行防盗链
这里需要使用两台Linux主机(一台充当防盗链服务器,一台充当盗链服务器),下表是它们所使用的操作系统以及IP地址. 两台Linux主机所使用的操作系统以及IP地址 主机名称 操作系统 IP地址 防盗 ...
- Git常用基础命令
要参与任何一个 Git 项目的协作,必须要了解该如何管理远程仓库.远程仓库是指托管在网络上的项目仓库,可能会有好多个,其中有些你只能读,另外有些可以写.同他人协作开发某 个项目时,需要管理这些远程仓库 ...
- mysql之子查询、视图、事务及pymysql等
数据准备 CREATE TABLE `emp` ( `id` int(0) NOT NULL AUTO_INCREMENT, `name` varchar(10) NOT NULL, `gender` ...
- 4.28(TG模拟赛)总结
1.挖地雷 题目背景 NOIp1996提高组第三题 题目描述 在一个地图上有N个地窖(N≤20),每个地窖中埋有一定数量的地雷.同时,给出地窖之间的连接路径.当地窖及其连接的数据给出之后,某人可以从任 ...
- haproxy 配置文件详解 之 ACL 智能负载均衡
由于HAProxy 可以工作在七层模型下, 因此,要实现 HAProxy 的强大功能,一定要使用强大灵活的ACL 规则,通过ACL 规则可以实现基于HAProxy 的智能负载均衡系统. HAProxy ...
- Android Studio 之 Navigation【2.数据的传递】
Android Studio 之 Navigation[2.数据的传递和过渡动画] 在资源navigation资源的xml文件中,在[目标界面] detialFragment中点击,在右边 Argum ...