[题解]bzoj4540 HNOI2016 序列
来源:互联网 发布:全国地址数据库 编辑:程序博客网 时间:2024/06/03 22:58
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
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
Solution
考虑序列中的某个数
对于平面矩形加法、平面矩形查询权值和的问题,我们按y从小到大扫。
设当前扫描线高度为H,矩形上界为up,矩形下界为down,左边为L,右边为R,当前矩形权值为val。
如果当前矩形还没有扫到上界,那么他在横坐标[L,R]范围内每个点的贡献为
如果当前矩形扫到了上界,即将退出,那么他将来在横坐标[L,R]范围内每个点的贡献为
代码:
#include<cstdio>#include<cstring>#include<algorithm>using namespace std;template<typename T>inline void read(T &x){ T f=1;char ch=getchar(); for(;ch<'0'||ch>'9';ch=getchar())if(ch=='-')f=-1; for(x=0;ch>='0'&&ch<='9';ch=getchar())x=x*10+ch-'0'; x*=f;}typedef long long LL;const int maxn=100010;int n,m,a[maxn],L[maxn],R[maxn],cnt,sta[maxn],top;LL ans[maxn];struct Line{ int l,r,y,f,id; bool operator<(Line b)const{ if(y==b.y)return f<b.f; return y<b.y; }}q[maxn<<2];struct Bit{ LL a[maxn],b[maxn]; Bit(){ memset(a,0,sizeof a); memset(b,0,sizeof b); } void Add(int x,LL val){ for(int i=x;i<=n;i+=(i&-i)) a[i]+=val,b[i]+=val*x; } void Add(int l,int r,LL val){ Add(l,val);Add(r+1,-val); } LL Query(int x){ LL ans=0; for(int i=x;i;i-=(i&-i)) ans+=a[i]*(x+1)-b[i]; return ans; } LL Query(int l,int r){ return Query(r)-Query(l-1); }}k,b;int main(){ read(n);read(m); for(int i=1;i<=n;i++)read(a[i]); for(int i=1;i<=n;i++){ while(top&&a[sta[top]]>=a[i])top--; top++;L[sta[top]=i]=sta[top-1]; } sta[top=0]=n+1; for(int i=n;i>=1;i--){ while(top&&a[sta[top]]>a[i])top--; top++;R[sta[top]=i]=sta[top-1]; } for(int i=1;i<=m;i++){ read(q[i].l),read(q[i].y); q[i].r=q[i].l;q[i].f=1;q[i].id=i; } cnt=m; for(int i=1;i<=n;i++){ q[++cnt].l=L[i]+1;q[cnt].f=0; q[cnt].r=i;q[cnt].y=i;q[cnt].id=i; q[++cnt].l=L[i]+1;q[cnt].f=2; q[cnt].r=i;q[cnt].y=R[i]-1;q[cnt].id=i; } sort(q+1,q+cnt+1); for(int i=1;i<=cnt;i++){ if(!q[i].f){ k.Add(q[i].l,q[i].r,a[q[i].id]); b.Add(q[i].l,q[i].r,(LL)a[q[i].id]*(1-q[i].id)); } else if(q[i].f==2){ k.Add(q[i].l,q[i].r,-a[q[i].id]); b.Add(q[i].l,q[i].r,(LL)a[q[i].id]*q[i].y); } else ans[q[i].id]=k.Query(q[i].l,n)*q[i].y+b.Query(q[i].l,n); } for(int i=1;i<=m;i++)printf("%lld\n",ans[i]); return 0;}
- [题解]bzoj4540 HNOI2016 序列
- bzoj4540: [Hnoi2016]序列
- bzoj4540: [Hnoi2016]序列
- BZOJ4540 HNOI2016 序列
- 【HNOI2016】【BZOJ4540】序列
- BZOJ4540 [Hnoi2016]序列
- bzoj4540【HNOI2016】序列
- bzoj4540: [Hnoi2016]序列
- 【BZOJ4540】【Hnoi2016】序列 线段树
- Bzoj4540:[Hnoi2016]序列:莫队+RMQ
- [bzoj4540][Hnoi2016]序列 莫队+RMQ
- 【bzoj4540】【HNOI2016】【序列】【莫队+st表】
- bzoj4540 [Hnoi2016]序列 (莫队+ST表+单调栈)
- [BZOJ4540]序列
- bzoj4540 序列
- HNOI2016题解
- 【HNOI2016】序列
- bzoj 4540: [Hnoi2016]序列
- WIN7无法卸载掉中文繁体注音输入法
- Hibernate面试题
- www
- UVA10366(细节模拟)
- 教你如何修改STM32系统时钟
- [题解]bzoj4540 HNOI2016 序列
- Easy RM to MP3 Converter漏洞分析报告
- 在easyui里写一个连接数据库的二级联动
- ThreadPoolExecutor
- opencv3学习之形态学(腐蚀/膨胀/开运算/闭运算/顶帽/黑帽)
- 抓包、python网络编程之tcp、udp例子
- log书写规范
- eclipse打开文件目录插件
- UVA