[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[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
输入文件的第一行包含两个整数n和q,分别代表序列长度和询问数。接下来一行,包含n个整数,以空格隔开
,第i个整数为ai,即序列第i个元素的值。接下来q行,每行包含两个整数l和r,代表一次询问。
Output
对于每次询问,输出一行,代表询问的答案。
Sample Input
Sample Output
HINT
1 ≤N,Q ≤ 100000,|Ai| ≤ 10^9
Solution
litc学长在暑假就讲过的题,现在临近寒假才过掉。。。
观察题目要求,容易得出若要优化暴力枚举,就要有技巧地统计每个元素产生的贡献
我们知道,任意元素x的贡献都可以表示为一个区间(l,r),其中a[l]<a[x] 且 a[r]<a[x]
询问时,我们用莫队离线做,分块一下
先按块编号和右端点下标分别为第一、第二关键字排序询问
区间最小值可以用st表预处理出来
对每个询问,我们用O(n^(1/2))时间进行转移,每次移除或加入一个元素时,统计此元素对当前区间[l,r]的贡献,算一下就行
最后输出就好了,我的程序有点慢,估计是变量名太长、函数太多
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define MaxN 100010
#define MaxBuf 1<<22
#define L long long
#define RG register
#define inline __inline__ __attribute__((always_inline))
#define Blue() (S == T&&(T=(S=B)+fread(B,1,MaxBuf,stdin),S == T) ? 0 : *S++)
#define dmin(x,y) ((x) < (y)?(x):(y)) char B[MaxBuf],*S=B,*T=B; inline void Rin(RG int &x) {
x=;RG int c=Blue(),f=;
for(; c < ||c > ; c=Blue())
if(c == )f=-;
for(; c > &&c < ; c=Blue())
x=(x<<)+(x<<)+c-;
x*=f; } L sl[MaxN],sr[MaxN],ans[MaxN]; int n,m,a[MaxN],block_size,log_pre[MaxN],pl[MaxN],pr[MaxN],_pb[MaxN]; struct Pr{
int fir,sec; Pr() {} Pr(RG int _,RG int __) : fir(_),sec(__) {} bool operator < (const Pr &other) const {
return fir < other.fir; } }f[MaxN][]; struct Request{
int l,r,id,belong; bool operator < (const Request &other) const {
if(belong == other.belong)
return r < other.r;
return belong < other.belong; } }Q[MaxN]; inline void Rmq_Init() {
for(RG int i=; i<; i++)
log_pre[<<i]=;
for(RG int i=; i<=n; i++)
log_pre[i]+=log_pre[i-];
for(RG int i=; i<=n; i++)
f[i][]=Pr(a[i],i);
for(RG int k=; k<; k++)
for(RG int i=; i<=n-(<<k)+; i++)
f[i][k]=dmin(f[i][k-],f[i+(<<k-)][k-]); } inline int Rmq_Query(RG int l,RG int r) {
RG int tim=log_pre[r-l+];
return dmin(f[l][tim],f[r-(<<tim)+][tim]).sec; } inline void Mono_Stack() {
RG int top=,i;
for(i=; i<=n; i++) {
while(top && a[_pb[top]] > a[i])
pr[_pb[top]]=i,top--;
_pb[++top]=i; }
while(top)pr[_pb[top]]=n+,top--;
for(i=n; i; i--) {
while(top && a[_pb[top]] > a[i])
pl[_pb[top]]=i,top--;
_pb[++top]=i; }
while(top)pl[_pb[top]]=,top--;
for(i=; i<=n; i++)
sl[i]=sl[pl[i]]+(L)a[i]*(i-pl[i]);
for(i=n; i; i--)
sr[i]=sr[pr[i]]+(L)a[i]*(pr[i]-i);
} inline L extend(RG int l,RG int r,RG bool c) {
RG int x=Rmq_Query(l,r);
return c ? (L)a[x]*(x-l+)+sl[r]-sl[x] :
(L)a[x]*(r-x+)+sr[l]-sr[x];
} inline void block_solve() {
RG L ans;
RG int l,r,i;
for(i=; i<=m; i++) {
if(i == ||Q[i].belong != Q[i-].belong)
r=(Q[i].belong-)*block_size,l=r+,ans=;
while(r < Q[i].r)
ans+=extend(l,++r,);
while(l < Q[i].l)
ans-=extend(l++,r,);
while(l > Q[i].l)
ans+=extend(--l,r,);
:: ans[Q[i].id]=ans; } } int main() {
Rin(n),Rin(m);
block_size=static_cast<int>(sqrt(n));
for(RG int i=; i<=n; i++)
Rin(a[i]);
for(RG int i=; i<=m; i++)
Rin(Q[i].l),Rin(Q[i].r),Q[i].id=i,Q[i].belong=(Q[i].l-)/block_size+;
std::sort(Q+,Q++m); Rmq_Init();
Mono_Stack();
block_solve(); for(RG int i=; i<=m; i++)
printf("%lld\n",ans[i]);
return ; }
[bzoj4540][Hnoi2016][序列] (莫队算法+单调栈+st表)的更多相关文章
- 【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]序列 莫队
4540: [Hnoi2016]序列 Time Limit: 20 Sec Memory Limit: 512 MB Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n ...
- [HNOI2016]序列(莫队,RMQ)
[HNOI2016]序列(莫队,RMQ) 洛谷 bzoj 一眼看不出来怎么用数据结构维护 然后还没修改 所以考虑莫队 以$(l,r-1) -> (l,r)$为例 对答案的贡献是$\Sigma_ ...
- BZOJ4540 Hnoi2016 序列 【莫队+RMQ+单调栈预处理】*
BZOJ4540 Hnoi2016 序列 Description 给定长度为n的序列:a1,a2,-,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,-,ar- ...
- BZOJ 4540 [Hnoi2016]序列 (单调栈 + ST表 + 莫队算法)
题目链接 BZOJ4540 考虑莫队算法. 这题难在$[l, r]$到$[l, r+1]$的转移. 根据莫队算法的原理,这个时候答案应该加上 $cal(l, r+1) + cal(l+1, r+1) ...
- BZOJ 3809 Gty的二逼妹子序列 莫队算法+分块
Description Autumn和Bakser又在研究Gty的妹子序列了!但他们遇到了一个难题. 对于一段妹子们,他们想让你帮忙求出这之内美丽度∈[a,b]的妹子的美丽度的种类数. 为了方便,我们 ...
- 【bzoj4542】[Hnoi2016]大数 莫队算法
题目描述 给出一个数字串,多次询问一段区间有多少个子区间对应的数为P的倍数.其中P为质数. 输入 第一行一个整数:P.第二行一个串:S.第三行一个整数:M.接下来M行,每行两个整数 fr,to,表示对 ...
- BZOJ.4540.[HNOI2016]序列(莫队/前缀和/线段树 单调栈 RMQ)
BZOJ 洛谷 ST表的一二维顺序一定要改过来. 改了就rank1了哈哈哈哈.自带小常数没办法. \(Description\) 给定长为\(n\)的序列\(A_i\).\(q\)次询问,每次给定\( ...
- bzoj 4540 [HNOI 2016] 序列 - 莫队算法 - Sparse-Table - 单调栈
题目传送门 传送点I 传送点II 题目大意 给定一个长度为$n$的序列.询问区间$[l, r]$的所有不同的子序列的最小值的和. 这里的子序列是连续的.两个子序列不同当且仅当它们的左端点或右端点不同. ...
随机推荐
- SpringMVC视图
SpringMVC视图机制详解[附带源码分析] 目录 前言 重要接口和类介绍 源码分析 编码自定义的ViewResolver 总结 参考资料 前言 SpringMVC是目前主流的Web MVC框架之一 ...
- T4模板demo
T4模板_根据DB生成实体类 为了减少重复劳动,可以通过T4读取数据库表结构,生成实体类,用下面的实例测试了一下 1.首先创建一个项目,并添加文本模板: 2.添加 文本模板: 3.向T4文本模板文 ...
- 2014.3.4-C语言学习小结
位操作: 知识点: 1.位运算符 2.位移运算符 1.将指定位设置为12.将指定位设置为03.获取指定位的内容 ==========================复习二进制 1.二进制转换 10-- ...
- Prototype,创建型模式
读书笔记_探索式测试_混合探索式测试 一.测试场景 1.讲述用户故事 2.描述需求 3.演示产品功能 4.演示集成场景 5.描述设置和安装 6.描述警告和出错情况 二.使用基于场景的探索式测试 1 ...
- MVC视图中的@Html.xxx(...)
ASP.NET MVC视图中的@Html.xxx(...) 问题 在视图页中@Html.xxx(...)是什么?如何被执行? 如下图所示: 解疑 视图页中@Html.xxx(...)涉及的内容有: ...
- 【IOS开发】SimPholders的使用
推荐一个Xocde开发工具 “SimPholders”,能够快速访问到你的模拟器文件夹,最重要的是完全免费! 官方地址
- IOS开发小功能2:二维码扫描界面的设计(横线上下移动)
效果图如上,实现的是一个二维码扫描界面. 下面我贴出线条上下移动的代码,至于二维码的代码是用的第三方库. 首先是整体的结构: 注意下面的库文件一个都不能少,否则会报错. TLTiltHighlight ...
- Hadoop 使用FileSystem API 读取数据
代码: package com.hadoop; import java.io.IOException; import java.io.InputStream; import java.net.URI; ...
- How To Configure Logging And Log Rotation In Apache On An Ubuntu VPS
Introduction The Apache web server can be configured to give the server administrator important info ...
- 2013集训.DAY21.A
随便点了一套刷,这套质量挺棒的,学了不少的东西,并且碰到了很久都没有打的题目 T1 card [指针技巧] 题1 集卡片 [问题描述] lzh小时候很喜欢收集卡片,他经常要去商店购买新到的卡片. 商店 ...