P3246 [HNOI2016]序列(莫队+单调栈+ST表)
[HNOI2016]序列
对于[l,r]→[l−1,r][l,r]\to[l-1,r][l,r]→[l−1,r]可以效仿移动右端点的方式预处理RiR_iRi以及gig_igi即可。
时间复杂度O(nlogn+nn)O(n\log n+n\sqrt{n})O(nlogn+nn)
注意莫队首先移动右端点因为初始化时,l=1,r=0l=1,r=0l=1,r=0
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
using pii=pair<int,int>;
using ll=long long;
constexpr int N=100010;
pii ST[N][22];
int lg[N];
int a[N],n,m;
int L[N],R[N],stk[N],top;
ll f[N],g[N];
int sz,pos[N];
void init(int n)
{lg[1]=0;for(int i=2;i<=n;i++) lg[i]=lg[i>>1]+1;for(int i=1;i<=n;i++) ST[i][0]={a[i],i};for(int k=1;k<=lg[n];k++)for(int i=1;i+(1<<k)-1<=n;i++) ST[i][k]=min(ST[i][k-1],ST[i+(1<<k-1)][k-1]);top=0;for(int i=1;i<=n;i++){while(top&&a[stk[top]]>a[i]) top--;L[i]=stk[top];stk[++top]=i;}stk[top=0]=n+1;for(int i=n;i>=1;i--){while(top&&a[stk[top]]>a[i]) top--;R[i]=stk[top];stk[++top]=i;}for(int i=1;i<=n;i++) f[i]=f[L[i]]+1ll*(i-L[i])*a[i];for(int i=n;i>=1;i--)g[i]=g[R[i]]+1ll*(R[i]-i)*a[i];sz=sqrt(n);for(int i=1;i<=n;i++) pos[i]=i/sz;}
int query(int l,int r)// [l,r]最小值的位置
{int k=lg[r-l+1];return min(ST[l][k],ST[r-(1<<k)+1][k]).second;
}
struct node
{int l,r;int id;bool operator<(const node&o)const{return pos[l]<pos[o.l]||pos[l]==pos[o.l]&&r<o.r;}
}q[N];
ll calcR(int l,int r)
{int p=query(l,r);return 1ll*a[p]*(p-l+1)+f[r]-f[p];
}
ll calcL(int l,int r)
{int p=query(l,r);return 1ll*a[p]*(r-p+1)+g[l]-g[p];
}
ll ans[N],res;
int main()
{ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);cin>>n>>m;for(int i=1;i<=n;i++) cin>>a[i];init(n);for(int i=1;i<=m;i++){int l,r;cin>>l>>r;q[i]={l,r,i};}sort(q+1,q+1+m);int l=1,r=0;for(int i=1;i<=m;i++){while(r<q[i].r) res+=calcR(l,++r);//首先考虑右端点while(r>q[i].r) res-=calcR(l,r--);while(l<q[i].l) res-=calcL(l++,r);while(l>q[i].l) res+=calcL(--l,r);ans[q[i].id]=res;}for(int i=1;i<=m;i++) cout<<ans[i]<<'\n';return 0;
}
注意我改了2小时,对比代码才改出来,无语了~~~
要加油哦~
P3246 [HNOI2016]序列(莫队+单调栈+ST表)相关推荐
- 洛谷 - P3246 [HNOI2016]序列(莫队+单调栈)
题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,再给出 mmm 次询问,每次询问需要回答一个区间 [l,r][l,r][l,r] 内所有子区间的最小值之和 题目分析:因为可以离线,所以考 ...
- hdu6989 (莫队+单调栈+ST表)
题意: 求l-r之间所有区间最大值最小值之和的期望,除法按照逆元来求; 题解: 看之前刚补的一道题目,那道题目跟这道题差不多,解释都在下面的链接中. [HNOI2016]序列 就是取余把人取傻了. # ...
- P3246 [HNOI2016]序列 莫队 + ST表 + 单调栈
传送门 文章目录 题意: 思路: Update 题意: 思路: 比较神奇的一个题,这里先介绍莫队的离线解法. 不难发现,用莫队来做最大的难点就是在进行区间移动的时候如何快速计算贡献. 比如[l,r]− ...
- HDU - 6989 Didn‘t I Say to Make My Abilities Average in the Next Life?! 莫队/单调栈 + 线段树/ST表在线
传送门 文章目录 题意: 思路: 题意: 思路: 考虑将贡献分开来算,先计算最大值,再算个最小值,之后答案就是((max+min)/2)/(len∗(len+1)/2)((max+min)/2)/(l ...
- 【BZOJ3956】Count,单调栈+ST表维护区间最大值
Time:2016.08.11 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: TA爷眼中的水题 首先有个特别的结论 总共的点对数不会超过2n 因为对于元素i来说,如果只考虑与比它高 ...
- 【BZOJ】3956 Count 单调栈+ST表
题目传送门 挺有思想的一题,但如果弄清楚了思路这题还是挺简单的. 首先我们可以发挥一下自己的脑洞,发现所有的好集对不可能相交. 那么我们可以刷两遍单调栈,求出每个点作为区间左端点或右端点的次数. 对于 ...
- P3246 [HNOI2016]序列(查询l-r中所有区间的最小值之和)
多校时做到了查询区间l-r中所有区间的最大值与最小之和的题目,有好多细节不太会处理,去看题解发现是一道差不多的原题,于是打算先把原题补一下. 题解: ST表+单调栈+莫队 看到计算区间最小值之和,不难 ...
- [BZOJ4542] [Hnoi2016] 大数 (莫队)
Description 小 B 有一个很大的数 S,长度达到了 N 位:这个数可以看成是一个串,它可能有前导 0,例如00009312345 .小B还有一个素数P.现在,小 B 提出了 M 个询问,每 ...
- 4542: [Hnoi2016]大数|莫队
HN一天考两个莫队是什么鬼..或者说莫队不是正确的姿势..? 考虑已经知道了 l..r l..r的答案新添入 r+1 r+1如何更新当前答案 需要先预处理出后缀 modp mod p的值 bi b_i ...
最新文章
- 算力觉醒后,智慧距离勃发就只差一个想法
- android StringBuffer实现换行
- html基于web2.0标准,晕倒:“用web2.0来制作符合标准的页面”
- python判断文件是否存在 中文_python如何判断文件是否存在
- idea 自动导入包操作及快捷键
- 专注创新勇突破 宏杉科技七策定纲存储之道
- 【Flash动画制作】
- java云之家发送信息_开发文档:考勤信息api - 云之家·开放平台
- python——algorithms模块
- 考研英语阅读12种解题技巧!码住!
- Unity Shader 实现简单的压扁效果
- POS接口与GE接口区别
- 胡喜:从 BASIC 到 basic ,蚂蚁金服技术要解决两个基本的计算问题
- 你是资讯控吗?——Web2.0智识管理简册
- eclipse中的javaEE插件
- 计网PPT 第九章 无线网络和移动网络
- Post请求报错405
- JavaScript大集合笔记
- 那些年,我们曾白嫖到的图床
- 163音乐点歌乱码分析以及解决办法
热门文章
- oracle 12c 多线程,Oracle 12c(12.1)中性能优化功能增强之通过参数THREADED_EXECTION使用多线程模型...
- linux多内核调度,linux-kernel – 如何在Linux内核(Samsung Exynos5422)中实现异构多处理(HMP)调度?...
- 问题 C: 【例2-3】围圈报数
- [JavaWeb-MySQL]多表查询概述
- [C++11]decltype在泛型编程中的使用举例
- C++实现线段树RMQ-单点修改,区间查询
- 高等数学上-赵立军-北京大学出版社-题解-练习4.5
- 多重背包问题以及二进制优化
- java调优方法,jvm监控工具
- redis持久化到mysql的方案_redis进阶: 数据持久化