hdu6989 (莫队+单调栈+ST表)
题意: 求l-r之间所有区间最大值最小值之和的期望,除法按照逆元来求;
题解: 看之前刚补的一道题目,那道题目跟这道题差不多,解释都在下面的链接中。
[HNOI2016]序列
就是取余把人取傻了。
#include<bits/stdc++.h>
#define int long long
using namespace std;const int maxn = 4e5+10;
const int mo=1e9+7;
int n,m;
int a[maxn];
int anshou[maxn],ansqian[maxn];
int pre[maxn],suf[maxn],pos[maxn];
int premax[maxn],sufmax[maxn];
int lmax[maxn],rmax[maxn];
void init(){stack<int> s;for(int i=n;i>=1;i--){while(!s.empty()&&a[s.top()]>=a[i]) s.pop();anshou[i]=s.empty()?n+1:s.top();s.push(i);}while(s.size()) s.pop();for(int i=1;i<=n;i++){while(!s.empty()&&a[s.top()]>=a[i]) s.pop();ansqian[i]=s.empty()?0:s.top();s.push(i);}while(s.size()) s.pop();for(int i=n;i>=1;i--){while(!s.empty()&&a[s.top()]<=a[i]) s.pop();rmax[i]=s.empty()?n+1:s.top();s.push(i);}while(s.size()) s.pop();for(int i=1;i<=n;i++){while(!s.empty()&&a[s.top()]<=a[i]) s.pop();lmax[i]=s.empty()?0:s.top();s.push(i);}for(int i=1;i<=n;i++){pre[i]=(pre[ansqian[i]]+(a[i]*(i-ansqian[i])%mo))%mo;premax[i]=(premax[lmax[i]]+(a[i]*(i-lmax[i]))%mo)%mo;}for(int i=n;i>=1;i--){suf[i]=(suf[anshou[i]]+(a[i]*(anshou[i]-i))%mo)%mo;sufmax[i]=(sufmax[rmax[i]]+(a[i]*(rmax[i]-i))%mo)%mo;}
}int stmin[maxn][21],stmax[maxn][21],mn[maxn];int stcmpmin(int x,int y){return a[x]<a[y]?x:y;
}
int stcmpmax(int x,int y){return a[x]>a[y]?x:y;
}
void init_st(){mn[0]=-1;for (int i=1;i<=n;i++){mn[i]=((i & (i-1))==0) ? mn[i-1]+1 : mn[i-1];stmin[i][0]=stmax[i][0]=i;}for(int j=1;j<=mn[n];j++)for(int i=1;i+(1<<j)-1<=n;i++){stmin[i][j]=stcmpmin(stmin[i][j-1],stmin[i+(1<<(j-1))][j-1]);stmax[i][j]=stcmpmax(stmax[i][j-1],stmax[i+(1<<(j-1))][j-1]);}
}
inline int rmq_min(int L,int R){int k=mn[R-L+1];return stcmpmin(stmin[L][k],stmin[R-(1<<k)+1][k]);
}
inline int rmq_max(int L,int R){int k=mn[R-L+1];return stcmpmax(stmax[L][k],stmax[R-(1<<k)+1][k]);
}struct Q{int l,r,k;
}q[maxn];struct rule{bool operator ()(const Q & a, const Q & b)const{if(pos[a.l]!=pos[b.l]) return a.l<b.l;if(pos[a.l]&1) return a.r<b.r;return a.r>b.r; //因为当l移动到另外一个分块时,r的移动会非常明显。}
};
int ans[maxn];inline int upl(int l,int r){int id=rmq_min(l,r);int maxid=rmq_max(l,r);return ((((r-id+1)*a[id])%mo+suf[l]-suf[id]+((r-maxid+1)*a[maxid])%mo+sufmax[l]-sufmax[maxid])%mo+mo)%mo;
}
inline int upr(int l,int r){int id=rmq_min(l,r);int maxid=rmq_max(l,r);return ((((id-l+1)*a[id])%mo+pre[r]-pre[id]+((maxid-l+1)*a[maxid])%mo+premax[r]-premax[maxid])%mo+mo)%mo;
}inline int mi(int a,int b)
{int ans=1;a%=mo;while (b){if (b&1) ans=ans*a%mo;b>>=1;a=a*a%mo;}return ans;
}signed main() {ios::sync_with_stdio(false);cin.tie(nullptr);//int n,m;
// freopen("1005.in","r",stdin);
// freopen("ans.txt","w",stdout);
//
// while(){//
// }int t;cin>>t;while(t--){cin>>n>>m;int sz=n/sqrt(m)+1;for(int i=1;i<=n;i++) cin>>a[i],pos[i]=i/sz;init();init_st();for(int i=1;i<=m;i++){cin>>q[i].l>>q[i].r;q[i].k=i;}sort(q+1,q+1+m,rule());int l=1,r=0,res=0;for(int i=1;i<=m;i++){while(q[i].l<l) res+=upl(--l,r);while(q[i].r>r) res+=upr(l,++r);while(q[i].l>l) res-=upl(l,r),l++;while(q[i].r<r) res-=upr(l,r),r--;int len=r-l+1;res=((res+mo)%mo+mo)%mo;ans[q[i].k]=(((res%mo)*mi((len*(len+1))%mo,mo-2)%mo)%mo+mo)%mo;}for(int i=1;i<=m;i++){//cout<<ans[i]<<endl;cout<<ans[i]<<endl;}}return 0;
}
hdu6989 (莫队+单调栈+ST表)相关推荐
- P3246 [HNOI2016]序列(莫队+单调栈+ST表)
[HNOI2016]序列 Tea神题解 Kelin神题解 对于莫队算法最主要的是如何快速算出[l,r]→[l,r+1][l,r]\to[l,r+1][l,r]→[l,r+1]对答案的贡献的变化. 当询 ...
- 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 ...
- 洛谷 - P3246 [HNOI2016]序列(莫队+单调栈)
题目链接:点击查看 题目大意:给出一个长度为 nnn 的序列,再给出 mmm 次询问,每次询问需要回答一个区间 [l,r][l,r][l,r] 内所有子区间的最小值之和 题目分析:因为可以离线,所以考 ...
- 【BZOJ3956】Count,单调栈+ST表维护区间最大值
Time:2016.08.11 Author:xiaoyimi 转载注明出处谢谢 传送门 思路: TA爷眼中的水题 首先有个特别的结论 总共的点对数不会超过2n 因为对于元素i来说,如果只考虑与比它高 ...
- 【BZOJ】3956 Count 单调栈+ST表
题目传送门 挺有思想的一题,但如果弄清楚了思路这题还是挺简单的. 首先我们可以发挥一下自己的脑洞,发现所有的好集对不可能相交. 那么我们可以刷两遍单调栈,求出每个点作为区间左端点或右端点的次数. 对于 ...
- POJ1821 单调队列//ST表 优化dp
http://poj.org/problem?id=1821 当我们在考虑内层循环j以及决策k的时候,我们可以把外层变量i看作定值,以此来优化dp状态转移方程. 题意 有n个工人准备铺m个连续的墙,每 ...
- 数据结构算法 | 单调栈
文章目录 算法概述 题目 下一个更大的元素 I 思路 代码 下一个更大元素 II 思路 代码 132 模式 思路 代码 接雨水 思路 算法概述 当题目出现 「找到最近一个比其大的元素」 的字眼时,自然 ...
- leetcode:6080. 使数组按非递减顺序排列【单调栈 + 合并】
分析 保存一个单调递减的stack,元素是(num, max+t) 遇到大于等于栈顶的,把栈顶的挪出来,然后记录同一次挪出的最大的max_t 如果挪完st还有剩余的话,max_t ++ 然后ans就是 ...
- 【HNOI2016】序列【莫队】【单调栈】【ST表】
题意:给定序列 aia_iai,qqq 次询问 [l,r][l,r][l,r] 所有子区间最小值之和. n,q≤105n,q\leq 10^5n,q≤105 这种题一眼看上去是离线线段树,但这题每移 ...
最新文章
- 汇编语言的码制转换小问题--求指教
- codeforces 476B.Dreamoon and WiFi 解题报告
- python游戏开发工程师_Python开发工程师-入门与实战视频课程
- 测试人员如何搭建自动打包部署平台?(具体详细步骤及下载地址)
- lua调用c 模块linux,Lua 调用自定义C模块
- mini2440驱动分析之ADC
- 2019届[月考01-03]高三理科数学试题参考答案
- java导出excel超出65536条处理
- 看不见的“网” ,一文读懂阿里云基础设施网络
- 微信小程序-图片上传功能的实现
- javaweb重定向——登录页面跳转到首页
- 关于transform-style:preserve-3d的些许明了
- 射灯安装方法图解_射灯安装图解
- android 电话录音功能,Android实现电话录音功能
- 【OpenCV入门】一些基本的图像处理
- accept函数(TCP)
- Caffe MNIST 手写数字识别(全面流程)
- 如何使用windows的计划任务?计划任务
- php decrypt,GitHub - qiling/php-decrypt: PHP Decrypt是一个跨平台用来解密PHP源码的扩展
- 《Android 博客gif图片制作》