BZOJ4540 Hnoi2016 序列


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]" role="presentation">a[1:1],a[2:2],a[3:3],a[1:2],a[2:3],a[1:3]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

  输入文件的第一行包含两个整数n和q,分别代表序列长度和询问数。接下来一行,包含n个整数,以空格隔开,第i个整数为ai,即序列第i个元素的值。接下来q行,每行包含两个整数l和r,代表一次询问。

Output

  对于每次询问,输出一行,代表询问的答案。

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

HINT

1 ≤N,Q ≤ 100000,|Ai| ≤ 10^9


先考虑把一段区间向左边延伸一个点

我们发现在这个新区间里,额外的贡献就是以l为左端点,l+1~r所有节点为右节点的贡献,然后我们显然是可以用前缀和处理以i为左端点,i+1~n所有点为右节点的答案。但是我们发现前缀和的信息只能从上一个比当前节点小的节点转化而来,又因为在这个区间里,区间的最小值向右的部分中答案就是区间最小值,所以我们ST表预处理一下,找到区间最小值,然后剩下的部分就用前缀和处理就好了

然后在处理前缀和的时候需要正反处理,用单调栈维护一下就好了

然后一定要注意莫队运算的顺序!!!!


#include<bits/stdc++.h>
using namespace std;
#define N 100010
#define LL long long
#define pi pair<LL,LL>
struct Node{LL l,r,id;}p[N];
LL n,m,w[N],lg2[N];
LL block[N],siz;
pi ST[N][20];
LL s[N],top;
LL sum1[N],sum2[N],ans[N],res=0;
bool cmp(Node a,Node b){
if(block[a.l]==block[b.l])return a.r<b.r;
return a.l<b.l;
}
pi compare(pi a,pi b){return (a.first<b.first)?a:b;}
void STpre(){
lg2[0]=-1;for(int i=1;i<=n;i++)lg2[i]=lg2[i>>1]+1;
for(LL i=1;i<=n;i++)ST[i][0]=(pi){w[i],i};
for(LL k=1;k<=18;k++)
for(LL i=1;i+(1<<k)-1<=n;i++)
ST[i][k]=compare(ST[i][k-1],ST[i+(1<<k-1)][k-1]);
}
LL query(LL l,LL r){
LL k=lg2[r-l+1];
return compare(ST[l][k],ST[r-(1<<k)+1][k]).second;
}
void init(){
s[top=0]=0;
for(LL i=1;i<=n;i++){
while(top&&w[i]<=w[s[top]])top--;
sum1[i]=sum1[s[top]]+(i-s[top])*w[i];
s[++top]=i;
}
s[top=0]=n+1;
for(LL i=n;i>=1;i--){
while(top&&w[i]<=w[s[top]])top--;
sum2[i]=sum2[s[top]]+(s[top]-i)*w[i];
s[++top]=i;
}
}
LL queryL(int l,int r){
int tmp=query(l,r);
return (r-tmp+1)*w[tmp]+sum2[l]-sum2[tmp];
}
LL queryR(int l,int r){
int tmp=query(l,r);
return (tmp-l+1)*w[tmp]+sum1[r]-sum1[tmp];
}
int main(){
scanf("%lld%lld",&n,&m);
for(LL i=1;i<=n;i++)scanf("%lld",&w[i]);
for(LL i=1;i<=m;i++)scanf("%lld%lld",&p[i].l,&p[i].r),p[i].id=i;
siz=sqrt(n);
for(LL i=1;i<=n;i++)block[i]=(i-1)/siz+1;
sort(p+1,p+m+1,cmp);
STpre();
init();
int l=1,r=0;
for(LL i=1;i<=m;i++){
while(r<p[i].r)res+=queryR(l,++r);
while(l>p[i].l)res+=queryL(--l,r);
while(r>p[i].r)res-=queryR(l,r--);
while(l<p[i].l)res-=queryL(l++,r);
ans[p[i].id]=res;
}
for(LL i=1;i<=m;i++)printf("%lld\n",ans[i]);
return 0;
}

BZOJ4540 Hnoi2016 序列 【莫队+RMQ+单调栈预处理】*的更多相关文章

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

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

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

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

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

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

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

  5. luogu 3246 莫队+RMQ+单调栈

    hnoi 2016 标签:题解 莫队 考虑左端点左移以及右端点右移产生的贡献 这样就可以由 \([l, r]\) 转移到另外的 \(4\) 个区间 \(f_{l, r}\) 表示右端点在 \(r\), ...

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

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

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

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

  8. BZOj 4540: [Hnoi2016]序列 [莫队 st表 预处理]

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

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

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

随机推荐

  1. C和C#两种方式实现邮件的简单发送

    内容为通过两种方式发送邮件--1.C语言发送邮件   2.C#发送邮件 一,C语言进行邮件的发送 C语言发送邮件的步骤的简单解析: 1.创建TCP连接    socket() 2.连接到邮箱服务器  ...

  2. MySQL索引最左原则

    通过实例理解单列索引.多列索引以及最左前缀原则 实例:现在我们想查出满足以下条件的用户id: 因为我们不想扫描整表,故考虑用索引. 单列索引: ALTER TABLE people ADD INDEX ...

  3. flask学习(四):debug模式

    一. 设置debug模式 1. flask 1.0之前 在app.run()中传入一个关键字参数debug,app.run(debug=True),就设置当前项目为debug模式 2. flask 1 ...

  4. Java对象的初始化顺序

    new一个对象时,该对象的初始化顺序如下 : 父类中的静态成员变量 父类中的静态代码块 子类中的静态成员变量 子类中的静态代码块 父类中的非静态变量 父类中的非静态代码块 父类构造函数 子类中的非静态 ...

  5. 《深入理解mybatis原理3》 Mybatis数据源与连接池

    <深入理解mybatis原理> Mybatis数据源与连接池 对于ORM框架而言,数据源的组织是一个非常重要的一部分,这直接影响到框架的性能问题.本文将通过对MyBatis框架的数据源结构 ...

  6. 第十天 1-9 rhel7-文件的归档和压缩

    大纲:文件的归档和压缩1.tar命令的使用及参数解析tar.gz.bz/bz2文件的创建.查看及解压zip/unzip命令的使用 一.文件的归档和压缩 在我们的计算机中,经常会遇到有好多文件名相似或作 ...

  7. CodeForces 297D Color the Carpet (脑补题)

    题意 一个h*w的矩阵上面涂k种颜色,并且每行相邻格子.每列相邻格子都有=或者!=的约束.要求构造一种涂色方案使得至少有3/4的条件满足. 思路 脑补神题--自己肯定想不出来T_T-- 官方题解: 2 ...

  8. JAVA运行war包

    set JAVA_OPTS=-Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m  java %JAVA_OPTS%  ...

  9. 2.spring cloud eureka client配置

    红色加粗内容表示修改部分 1.把server项目打成jar包并启动 在项目根目录cmd执行  mvn clean package -Dmaven.test.skip=true mavne仓库地址建议 ...

  10. 【zznu-夏季队内积分赛3-I】逛超市

    题目描述 “别人总说我瓜,其实我一点也不瓜,大多数时候我都机智的一批“我宝儿姐背包学的太差了,你们谁能帮我解决这道题,我就让他做我的男朋友!宝儿姐现在在逛超市,超市里的种类实在是太多了,每种都有很多很 ...