『序列 莫队 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 ...
随机推荐
- MES助力伊利集团打造智慧工厂
1.项目背景介绍 在国家政策和事业部.工厂的实际需求双重背景下,2016年7-9月期间,伊利集团信息部门.业务部门,先后与国内外领先的设备和咨询公司进行了智能制造.智慧工厂等话题的沟通交流,并组织实地 ...
- 集成学习 - Bagging
认识 Bagging 的全称为 (BootStrap Aggregation), 嗯, 咋翻译比较直观一点呢, 就有放回抽样 模型训练? 算了, 就这样吧, 它的Paper是这样的: Algorith ...
- Idea中Spring整合MyBatis框架中配置文件中对象注入问题解决方案
运行环境:Spring框架整合MaBitis框架 问题叙述: 在Spring配置文件applicationContext-mybatis.xml中配置好mybatis之后 <?xml versi ...
- Ningx的基本使用
Ningx的基本使用 user www; worker_processes 2; error_log logs/error.log info; pid logs/nginx.pid; even ...
- linux下使用shell发送http请求
一.curl 1. get请求 curl命令默认下就是使用get方式发送http请求. curl www.baidu.com 2. post请求 使用-d参数,形式如下: curl -d " ...
- Windows WoW64浅析
WOW64(Windows-On-Windows 64bit)是X64 Windows操作系统的一个子系统,为32位应用程序提供运行环境.类似的还有WOW32子系统,负责在32位Windows系统上运 ...
- vue+ typescript 使用parcel 构建
parcel 是一个零配置的前端构建工具,相比webpack 更快,同时使用简单以下是 一个简单的使用typescript 开发vue 应用,同时使用parcel 构建,同时集成了docker 构建, ...
- NOIP2019翻车前计划以及日记
目前只有日记和草拟计划(Sua机洗点~),等停课后会实施计划,试行期为一天. 根据试行期的学习效果制定计划. update 1:试行期结束,完全可以按计划来. update 2:计划暂时变更,以适应我 ...
- [no_perms] Private mode enable, only admin can publish this module
在使用npm publish是出现了错误: npm ERR! code E403 npm ERR! 403 Forbidden - PUT https://registry.npm.taobao.or ...
- 第01组 Alpha冲刺(6/6)
队名:007 组长博客: https://www.cnblogs.com/Linrrui/p/11914337.html 作业博客: https://edu.cnblogs.com/campus/fz ...