【[HNOI2016]序列】
莫队好题啊
莫队来做这个题的难点就是考虑如何在\(O(1)\)时间内由\([l,r]\)转移到\([l,r+1]\)
显然加入\(r+1\)这个数之后会和之前所有的位置都产生一个区间,就是要去快速求出这个区间的和
我们先利用单调栈,扫出每个点往左往右都能扩展到哪里,在处理出一个数组\(dp[i]\)表示从\(1\),\(2\),\(3\)$$...$ \(i-1\),\(i\)与\(i\)形成的所有区间最小值的和
有了这个单调栈处理出来的东西就很好处理了
之后我们考虑添加\(r+1\)这个点,我们先用\(st\)查出\([l,r+1]\)的最小值\(x\)和最小值的位置\(t\),之后就分成了两段
\([l,t]\)都是按照整个区间的最小值来算的,于是直接就是\((t-l+1)\times x\)
\([t+1,r+1]\)是有所不同的,但是这个时候我们直接用\(dp[r+1]-dp[t]\)就可以表示出来了
之后有几个坑点
莫队转移的之后要时刻保证\(l<r\)
\(add(i++)\),尽管穿进去的值是\(i\),但是如果再调用全局变量会是\(i+1\)
代码
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
#define re register
#define LL long long
#define maxn 100005
inline int read()
{
re char c=getchar();int x=0,r=1;
while(c<'0'||c>'9') {if(c=='-') r=-1;c=getchar();}
while(c>='0'&&c<='9') x=(x<<3)+(x<<1)+c-48,c=getchar();return x*r;
}
struct Ask{int x,y,rk;}a[maxn];
LL Ans[maxn];
int St[maxn][18],log_2[maxn],t[maxn][18];
int ls[maxn],rs[maxn],st[maxn],top;
LL dp[maxn],f[maxn];
LL ans;
int n,m,sz,l,r;
inline std::pair<int,int> ask(int L,int R)
{
int k=log_2[R-L+1];
if(St[L][k]<St[R-(1<<k)+1][k]) return std::make_pair(t[L][k],St[L][k]);
return std::make_pair(t[R-(1<<k)+1][k],St[R-(1<<k)+1][k]);
}
inline int cmp(Ask A,Ask B){if(A.x/sz==B.x/sz) return A.y<B.y;return A.x<B.x;}
inline void solve_r(int x,LL opt)
{
LL now=dp[x]; std::pair<int,int> pii=ask(l,x);
now=now-(LL)dp[pii.first]+(LL)pii.second*(LL)(pii.first-l+1);ans+=opt*now;
}
inline void solve_l(int x,LL opt)
{
LL now=f[x]; std::pair<int,int> pii=ask(x,r);
now=now-(LL)f[pii.first]+(LL)pii.second*(LL)(r-pii.first+1);ans+=opt*now;
}
int main()
{
n=read(),m=read();memset(St,20,sizeof(St));
for(re int i=1;i<=n;i++) St[i][0]=read(),t[i][0]=i;
for(re int i=2;i<=n;i++) log_2[i]=1+log_2[i>>1];
for(re int j=1;j<=17;j++)
for(re int i=1;i+(1<<j)-1<=n;i++)
if(St[i][j-1]<St[i+(1<<(j-1))][j-1]) St[i][j]=St[i][j-1],t[i][j]=t[i][j-1];
else St[i][j]=St[i+(1<<(j-1))][j-1],t[i][j]=t[i+(1<<(j-1))][j-1];
sz=std::sqrt(n);
for(re int i=1;i<=m;i++) a[i].x=read(),a[i].y=read(),a[i].rk=i;
std::sort(a+1,a+m+1,cmp);
for(re int i=1;i<=n;i++) {while(top&&St[st[top]][0]>St[i][0]) rs[st[top]]=i,top--;st[++top]=i;}
while(top) rs[st[top]]=n+1,top--;
for(re int i=n;i;--i) {while(top&&St[st[top]][0]>St[i][0]) ls[st[top]]=i,top--;st[++top]=i;}
while(top) ls[st[top]]=0,top--;
for(re int i=1;i<=n;i++) dp[i]=(LL)St[i][0]*(LL)(i-ls[i])+dp[ls[i]];
for(re int i=n;i;--i) f[i]=(LL)St[i][0]*(LL)(rs[i]-i)+f[rs[i]];
l=1,r=1,ans=St[1][0];
for(re int i=1;i<=m;i++)
{
while(l>a[i].x) solve_l(--l,1);
while(r<a[i].y) solve_r(++r,1);
while(l<a[i].x) solve_l(l++,-1);
while(r>a[i].y) solve_r(r--,-1);
Ans[a[i].rk]=ans;
}
for(re int i=1;i<=m;i++) printf("%lld\n",Ans[i]);
return 0;
}
【[HNOI2016]序列】的更多相关文章
- BZOj 4540: [Hnoi2016]序列 [莫队 st表 预处理]
4540: [Hnoi2016]序列 题意:询问区间所有子串的最小值的和 不强制在线当然上莫队啦 但是没想出来,因为不知道该维护当前区间的什么信息,维护前后缀最小值的话不好做 想到单调栈求一下,但是对 ...
- 【LG3246】[HNOI2016]序列
[LG3246][HNOI2016]序列 题面 洛谷 题解 60pts 对于每个位置\(i\),单调栈维护它往左第一个小于等于它的位置\(lp_i\)以及往右第一个小于它的位置\(rp_i\). 那么 ...
- 4540: [Hnoi2016]序列
4540: [Hnoi2016]序列 https://www.lydsy.com/JudgeOnline/problem.php?id=4540 分析: 莫队+RMQ+单调栈. 考虑加入一个点后,区间 ...
- [BZOJ4540][HNOI2016]序列 莫队
4540: [Hnoi2016]序列 Time Limit: 20 Sec Memory Limit: 512 MB Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n ...
- BZOJ4540 Hnoi2016 序列 【莫队+RMQ+单调栈预处理】*
BZOJ4540 Hnoi2016 序列 Description 给定长度为n的序列:a1,a2,-,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,-,ar- ...
- 【BZOJ4540】[Hnoi2016]序列 莫队算法+单调栈
[BZOJ4540][Hnoi2016]序列 Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,a ...
- [Bzoj4540][Hnoi2016] 序列(莫队 + ST表 + 单调队列)
4540: [Hnoi2016]序列 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 1567 Solved: 718[Submit][Status] ...
- [HNOI2016]序列 CDQ+DP
[HNOI2016]序列 CDQ 链接 loj 思路 一个点最小变为l,最大变为r,不变的时候为v 那么j能在i前面就要满足. \(j<i\) \(r[j]<=v[i]\) \(v[j]& ...
- 题解-[HNOI2016]序列
题解-[HNOI2016]序列 [HNOI2016]序列 给定 \(n\) 和 \(m\) 以及序列 \(a\{n\}\).有 \(m\) 次询问,每次给定区间 \([l,r]\in[1,n]\),求 ...
- P6604 [HNOI2016]序列 加强版
*I. P6604 [HNOI2016]序列 加强版 摘自学习笔记 简单树论 笛卡尔树部分例题 I. 和 P6503 比较类似.我们设 \(f_i\) 表示全局以 \(i\) 结尾的子区间的最小值之和 ...
随机推荐
- [C语言] 数据结构-算法效率的度量方法-事前分析估算方法
事前分析估算方法:在计算机程序编制前,依据统计方法对算法进行估算,抛开与计算机硬件软件有关的因素,一个程序的运行时间,依赖于算法的,好坏和问题的输入规模,所谓问题输入规模是指输入量的多少 推导过程,比 ...
- VisualVM监控远程阿里云主机
一.前言 使用VisualVM监控远程主机,主要是要在远程主机上部署JMX服务和jstat服务,jstat服务的部署花了我半天的时间,而且,网上的资基本都是缺胳膊少腿的,没有一篇是一个整体(行得通的) ...
- Java数据类型和不同数据类型在JVM内存分配
1.java数据类型分类 Java语言是强类型(Strongly typed)语言,强类型包含两方面的含义:①所有的变量必须先声明,后使用:②指定类型的变量只能接受类型与之匹配的值.这意味着每个变量和 ...
- 【学习笔记】--- 老男孩学Python,day13 生成器,生成器函数,各种推倒式和生成器表达式
1. 生成器和生成器函数 生成器的本质就是迭代器 生成器的三种创建办法: 1.通过生成器函数 2.通过生成器表达式创建生成器 3.通过数据转换 2. 生成器函数: 函数中包含了yield的就是生成 ...
- ASP.NET MVC 简单分页代码
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- [微信小程序] 微信小程序富文本-wxParse的使用
最近小程序蛮火的,公司要做于是学了一点点小程序 不知道你们有没有遇到过这种问题: 从公司服务器获取的文章内容是有HTML标签格式的一段内容,但是微信是不支持这些标签的,怎么办呢? 1.一般网站后台的文 ...
- SESSION机制(转)
转自:http://www.cnblogs.com/zyf-zhaoyafei/p/4477175.html 一:Session与Cookie Session:在服务器端创建并存放在服务器的内存中的, ...
- RabbitMQ,Windows环境下安装搭建
切入正题:RabbitMQ的Windows环境下安装搭建 一.首先安装otp_win64_20.1.exe,,, 二.然后安装,rabbitmq-server-3.6.12.exe, 安装完成后,在服 ...
- vip会员统计表 (vip等级是灵活配置的 非写死1是金卡用户 2是什么 等)
一个非常常见的报表,分析会员组成比例 以及最新增长情况 和上月同期会员增长情况. 比较特殊一点的是 报表中的 普通会员 和 金卡会员 临时会员 银卡会员 等列 都是根据会员等级配置表动态生成的(即 ...
- 优雅的实现多类型列表的Adapter
1引言 在开发中经常会遇到,一个列表(RecyclerView)中有多种布局类型的情况.前段时间,看到了这篇文章 [译]关于 Android Adapter,你的实现方式可能一直都有问题(http:/ ...