点此看题面

大致题意: 求出一个序列的一段区间中所有子序列最小值之和。

莫队

这道题其实是一道莫队题。

但是需要大量的预处理。

预处理

先考虑预处理两个数组\(lst_i\)和\(nxt_i\),分别表示在第\(i\)个元素左边、右边第一个小于它的元素的位置

这可以直接用单调栈实现\(O(n)\)预处理。

然后,我们考虑预处理出\(sum_i\)和\(lst_i\)两个数组,分别存储在\([1,i]\)区间右侧插入一个数的代价在\([i,n]\)区间左侧插入一个数的代价,即\(\sum_{k=1}^i Min_{x=1}^k a_x\)和\(\sum_{k=i}^n Min_{x=k}^n a_x\)。

这可以在预处理\(lst_i\)和\(nxt_i\)的同时这样预处理:

sum[i]=sum[lst[i]]+1LL*a[i]*(i-lst[i]);//suf数组同理

区间移动

接下来,我们要考虑如何处理区间移动(以在左边插入一个数为例)。

首先,我们找到这个区间内最小的数所在的位置\(p\),显然,第\([p,R]\)的位置与\(L\)所构成的区间的最小值都是\(a_p\)。

然后就考虑\([L,p-1]\)区间内的贡献。

考虑到\([L,p]\)区间内\(a_p\)最小,因此\(suf_L\)值肯定是从\(suf_p\)经过若干次转移得来的。

因此它就满足前缀和性质了,可以直接通过\(suf_L-suf_p\)来计算贡献。

而其他的区间移动操作也是同理的,具体实现详见代码。

代码

#include<bits/stdc++.h>
#define N 100000
#define LL long long
#define INF 1e9
#define Gmin(x,y) (x>(y)&&(x=(y)))
using namespace std;
int n,query_tot,a[N+5];
class Class_FIO
{
private:
#define Fsize 100000
#define tc() (A==B&&(B=(A=Fin)+fread(Fin,1,Fsize,stdin),A==B)?EOF:*A++)
#define pc(ch) (void)(FoutSize<Fsize?Fout[FoutSize++]=ch:(fwrite(Fout,1,Fsize,stdout),Fout[(FoutSize=0)++]=ch))
int f,Top,FoutSize;char ch,*A,*B,Fin[Fsize],Fout[Fsize],Stack[Fsize];
public:
Class_FIO() {A=B=Fin;}
inline void read(int &x) {x=0,f=1;while(!isdigit(ch=tc())) f=ch^'-'?1:-1;while(x=(x<<3)+(x<<1)+(ch&15),isdigit(ch=tc()));x*=f;}
inline void writeln(LL x) {if(!x) return pc('0'),pc('\n');x<0&&(pc('-'),x=-x);while(x) Stack[++Top]=x%10+48,x/=10;while(Top) pc(Stack[Top--]);pc('\n');}
inline void clear() {fwrite(Fout,1,FoutSize,stdout),FoutSize=0;}
}F;
class Class_CaptainMotao
{
private:
#define AddLeft() {register int p=RMQ.GetMin(--L,R);res+=1LL*a[p]*(R-p+1)+I.suf[L]-I.suf[p];}
#define AddRight() {register int p=RMQ.GetMin(L,++R);res+=1LL*a[p]*(p-L+1)+I.sum[R]-I.sum[p];}
#define DelLeft() {register int p=RMQ.GetMin(L,R);res-=1LL*a[p]*(R-p+1)+I.suf[L++]-I.suf[p];}
#define DelRight() {register int p=RMQ.GetMin(L,R);res-=1LL*a[p]*(p-L+1)+I.sum[R--]-I.sum[p];}
int S;LL ans[N+5];
class Class_Initer//初始化
{
private:
int Top,lst[N+5],nxt[N+5],Stack[N+5];
public:
LL sum[N+5],suf[N+5];
inline void Init()
{
register int i;
for(i=1;i<=n;++i) {while(Top&&a[Stack[Top]]>=a[i]) --Top;lst[i]=Stack[Top],Stack[++Top]=i,sum[i]=sum[lst[i]]+1LL*a[i]*(i-lst[i]);}
for(Stack[Top=0]=n+1,i=n;i;--i) {while(Top&&a[Stack[Top]]>=a[i]) --Top;nxt[i]=Stack[Top],Stack[++Top]=i,suf[i]=suf[nxt[i]]+1LL*a[i]*(nxt[i]-i);}
}
}I;
class Class_RMQ//RMQ
{
private:
#define LogN 20
int Log2[N+5];
struct RMQ_data
{
int val,pos;
inline friend bool operator < (RMQ_data x,RMQ_data y) {return x.val<y.val;}
RMQ_data(int x=0,int y=0):val(x),pos(y){}
}Min[N+5][LogN+5];
public:
inline void Init()
{
register int i,j;
for(i=2;i<=n;++i) Log2[i]=Log2[i>>1]+1;
for(i=1;i<=n;++i) Min[i][0]=RMQ_data(a[i],i);
for(j=1;(1<<j-1)<=n;++j) for(i=1;i+(1<<j-1)<=n;++i) Min[i][j]=min(Min[i][j-1],Min[i+(1<<j-1)][j-1]);
}
inline int GetMin(int l,int r) {register int k=Log2[r-l+1];return min(Min[l][k],Min[r-(1<<k)+1][k]).pos;}
}RMQ;
struct Query
{
int l,r,pos,bl;
inline friend bool operator < (Query x,Query y) {return x.bl^y.bl?x.bl<y.bl:(x.bl&1?x.r<y.r:x.r>y.r);}
}q[N+5];
public:
inline void Solve()
{
register int i,L=1,R=0;register LL res=0;
for(I.Init(),RMQ.Init(),S=sqrt(n),i=1;i<=query_tot;++i) F.read(q[q[i].pos=i].l),F.read(q[i].r),q[i].bl=(q[i].l-1)/S+1;
for(sort(q+1,q+query_tot+1),i=1;i<=query_tot;++i)//处理询问
{
while(R<q[i].r) AddRight();
while(L>q[i].l) AddLeft();
while(R>q[i].r) DelRight();
while(L<q[i].l) DelLeft();
ans[q[i].pos]=res;
}
for(i=1;i<=query_tot;++i) F.writeln(ans[i]);
}
}C;
int main()
{
register int i;
for(F.read(n),F.read(query_tot),i=1;i<=n;++i) F.read(a[i]);
return C.Solve(),F.clear(),0;
}

【BZOJ4540】 [HNOI2016] 序列(莫队)的更多相关文章

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

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

  2. [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 ...

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

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

  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. BZOj 4540: [Hnoi2016]序列 [莫队 st表 预处理]

    4540: [Hnoi2016]序列 题意:询问区间所有子串的最小值的和 不强制在线当然上莫队啦 但是没想出来,因为不知道该维护当前区间的什么信息,维护前后缀最小值的话不好做 想到单调栈求一下,但是对 ...

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

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

  7. 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 ...

  8. 洛谷P3246 [HNOI2016]序列 [莫队]

    传送门 思路 看到可离线.无修改.区间询问,相信一定可以想到莫队. 然而,莫队怎么转移是个大问题. 考虑\([l,r]\rightarrow[l,r+1]\)时答案会怎样变化?(左端点变化时同理) \ ...

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

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

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

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

随机推荐

  1. The Knuth-Morris-Pratt Algorithm in my own words(转)

    origianl For the past few days, I’ve been reading various explanations of the Knuth-Morris-Pratt str ...

  2. 说一说solr在tomcat,jetty上的运行和安装优缺点

    本文是我从别的文章中组合而成的,结合自己实际操作进行了修改. Solr是什么 Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器.Solr提供了比Lu ...

  3. Gson本地和服务器环境不同遇到的Date转换问题 Failed to parse date []: Invalid time zone indicator

    GoogleGson在处理Date格式时有个小陷阱,在不同环境中部署时可能会遇到问题. Gson默认处理Date对象的序列化/反序列化是通过一个SimpleDateFormat对象来实现的,通过下面的 ...

  4. html_entity_decode与htmlentities函数

    htmlentities() 函数把字符转换为 HTML 实体.html_entity_decode() 函数把 HTML 实体转换为字符.例子:$a = '<div> <p> ...

  5. POJ1023 The Fun Number System

    题目来源:http://poj.org/problem?id=1023 题目大意: 有一种有趣的数字系统.类似于我们熟知的二进制,区别是每一位的权重有正有负.(低位至高位编号0->k,第i位的权 ...

  6. JS精粹知识点和我的解释

    函数若是不return则默认返回undefined const value=()=>{ let a=3; } let value_test; console.log(value(),value_ ...

  7. bzoj1004 [HNOI2008]Cards【Burnside/Polya】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1004 一道好题,但并不是好在融合了三个“考点”(计数,背包dp,逆元),其实背包dp以及求逆 ...

  8. 025 Reverse Nodes in k-Group 每k个一组翻转链表

    给出一个链表,一次翻转 k 个指针节点,并返回修改后的链表.k 是一个正整数,并且小于等于链表的长度.如果指针节点的数量不是 k 的整数倍,那么最后剩余的节点应当保持原来的样子.你不应该改变节点的值, ...

  9. 010 Regular Expression Matching 正则表达式匹配

    Implement regular expression matching with support for '.' and '*'.'.' Matches any single character. ...

  10. Python3.5 调用Ansible 执行命令

    ansible.py #!/usr/bin/env python3 # -*- coding: utf-8 -*- import os import tempfile from collections ...