强烈安利:http://blog.csdn.net/qq_34637390/article/details/51313126

这篇讲标记讲的非常好,这个标记非常神奇……

首先last表示扫描到last这个点了,val[x]表示x到last中的最小值,sum[x]表示last分别等于1,2,3....last时的和(也就是所有val历史版本的和)

然后答案就是当前last扫到r,l到r之间所有sum的和(稍微画一下就理解了

然后考虑现在要挪动last,新的last的影响范围是他之前第一个比他小的位置(单调栈维护)到新last这一段,考虑对这一段的修改,就是把所有的val修改成a[last],sum加上原来的val

这里用abcd做lazytag,每次修改这样搞一下:(以下为截图

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N=100005;
int n,m,a[N],top,s[N];
long long ans[N];
struct wen
{
int l,r,id;
}q[N];
bool cmp(const wen &a,const wen &b)
{
return a.r<b.r;
}
struct lazy
{
long long a,b,c,d;
lazy(long long A=0,long long B=0,long long C=0,long long D=0)
{
a=A,b=B,c=C,d=D;
}
lazy operator + (const lazy &y) const
{
return lazy(a*y.a,y.b+b*y.a,c+y.c*a,d+y.d+b*y.c);
}
};
struct qwe
{
int l,r;
long long val,sum;
lazy lz;
}t[N<<2];
int read()
{
int r=0,f=1;
char p=getchar();
while(p>'9'||p<'0')
{
if(p=='-')
f=-1;
p=getchar();
}
while(p>='0'&&p<='9')
{
r=r*10+p-48;
p=getchar();
}
return r*f;
}
void build(int ro,int l,int r)
{
t[ro].l=l,t[ro].r=r,t[ro].lz=lazy(1,0,0,0);
if(l==r)
return;
int mid=(l+r)>>1;
build(ro<<1,l,mid);
build(ro<<1|1,mid+1,r);
}
void add(int ro,lazy p)
{
t[ro].sum+=p.c*t[ro].val+p.d*(t[ro].r-t[ro].l+1);
t[ro].val=p.a*t[ro].val+p.b*(t[ro].r-t[ro].l+1);
t[ro].lz=t[ro].lz+p;
}
void pd(int ro)
{
if(t[ro].lz.a!=1||t[ro].lz.b||t[ro].lz.c||t[ro].lz.d)
{
add(ro<<1,t[ro].lz);
add(ro<<1|1,t[ro].lz);
t[ro].lz=lazy(1,0,0,0);
}
}
void update(int ro,int l,int r,lazy p)
{
if(t[ro].l==l&&t[ro].r==r)
{
add(ro,p);
return;
}
pd(ro);
int mid=(t[ro].l+t[ro].r)>>1;
if(r<=mid)
update(ro<<1,l,r,p);
else if(l>mid)
update(ro<<1|1,l,r,p);
else
{
update(ro<<1,l,mid,p);
update(ro<<1|1,mid+1,r,p);
}
t[ro].sum=t[ro<<1].sum+t[ro<<1|1].sum;
t[ro].val=t[ro<<1].val+t[ro<<1|1].val;
}
long long ques(int ro,int l,int r)
{
if(t[ro].l==l&&t[ro].r==r)
return t[ro].sum;
pd(ro);
int mid=(t[ro].l+t[ro].r)>>1;
if(r<=mid)
return ques(ro<<1,l,r);
else if(l>mid)
return ques(ro<<1|1,l,r);
else
return ques(ro<<1,l,mid)+ques(ro<<1|1,mid+1,r);
}
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
a[i]=read();
for(int i=1;i<=m;i++)
q[i].l=read(),q[i].r=read(),q[i].id=i;
sort(q+1,q+1+m,cmp);
build(1,1,n);
for(int i=1,j=1;i<=n;i++)
{
while(top&&a[s[top]]>=a[i])
top--;
update(1,s[top]+1,i,lazy(0,a[i],0,0));
add(1,lazy(1,0,1,0));
s[++top]=i;
for(;j<=m&&q[j].r==i;j++)
ans[q[j].id]=ques(1,q[j].l,q[j].r);
}
for(int i=1;i<=m;i++)
printf("%lld\n",ans[i]);
return 0;
}

bzoj 4540: [Hnoi2016]序列【单调栈+线段树】的更多相关文章

  1. 洛谷P4198 楼房重建 单调栈+线段树

    正解:单调栈+线段树 解题报告: 传送门! 首先考虑不修改的话就是个单调栈板子题昂,这个就是 然后这题的话,,,我怎么记得之前考试好像有次考到了类似的题目昂,,,?反正我总觉着这方法似曾相识的样子,, ...

  2. 2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树)

    2018宁夏邀请赛 L Continuous Intervals(单调栈+线段树) 传送门:https://nanti.jisuanke.com/t/41296 题意: 给一个数列A 问在数列A中有多 ...

  3. BZOj 4540: [Hnoi2016]序列 [莫队 st表 预处理]

    4540: [Hnoi2016]序列 题意:询问区间所有子串的最小值的和 不强制在线当然上莫队啦 但是没想出来,因为不知道该维护当前区间的什么信息,维护前后缀最小值的话不好做 想到单调栈求一下,但是对 ...

  4. BZOJ.4540.[HNOI2016]序列(莫队/前缀和/线段树 单调栈 RMQ)

    BZOJ 洛谷 ST表的一二维顺序一定要改过来. 改了就rank1了哈哈哈哈.自带小常数没办法. \(Description\) 给定长为\(n\)的序列\(A_i\).\(q\)次询问,每次给定\( ...

  5. BZOJ 4540 [Hnoi2016]序列 (单调栈 + ST表 + 莫队算法)

    题目链接  BZOJ4540 考虑莫队算法. 这题难在$[l, r]$到$[l, r+1]$的转移. 根据莫队算法的原理,这个时候答案应该加上 $cal(l, r+1) + cal(l+1, r+1) ...

  6. 【bzoj4540】[Hnoi2016]序列 单调栈+离线+扫描线+树状数组区间修改区间查询

    题目描述 给出一个序列,多次询问一个区间的所有子区间最小值之和. 输入 输入文件的第一行包含两个整数n和q,分别代表序列长度和询问数.接下来一行,包含n个整数,以空格隔开,第i个整数为ai,即序列第i ...

  7. BZOJ 4540 [Hnoi2016]序列 | 莫队 详细题解

    传送门 BZOJ 4540 题解 --怎么说呢--本来想写线段树+矩阵乘法的-- --但是嘛--yali的机房太热了--困--写不出来-- 于是弃疗,写起了莫队.(但是我连莫队都想不出来!) 首先用单 ...

  8. The Preliminary Contest for ICPC China Nanchang National Invitational I. Max answer (单调栈+线段树)

    题目链接:https://nanti.jisuanke.com/t/38228 题目大意:一个区间的值等于该区间的和乘以区间的最小值.给出一个含有n个数的序列(序列的值有正有负),找到该序列的区间最大 ...

  9. 网络赛 I题 Max answer 单调栈+线段树

    题目链接:https://nanti.jisuanke.com/t/38228 题意:在给出的序列里面找一个区间,使区间最小值乘以区间和得到的值最大,输出这个最大值. 思路:我们枚举每一个数字,假设是 ...

随机推荐

  1. HDU 1402 大数乘法 FFT、NTT

    A * B Problem Plus Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Other ...

  2. loj6158 A+B Problem (扩展KMP)

    题目: https://loj.ac/problem/6158 分析: 先把S串逆置,就是从低位向高位看 我们再弄个T串,S串前面有x个连续的0,那么T串前面也有x个连续的0 第x+1位,满足S[x+ ...

  3. Spring Boot应用的启动和停止(Spring Boot应用通过start命令启动)

    Spring Boot,作为Spring框架对“约定优先于配置(Convention Over Configuration)”理念的最佳实践的产物,它能帮助我们很快捷的创建出独立运行.产品级别的基于S ...

  4. Node.js+Web TWAIN,实现Web文档扫描和图像上传

      目录(?)[+] 通过Dynamic Web TWAIN SDK和Node.js的组合,只需要几行代码就可以实现在浏览器中控制扫描仪,获取图像后上传到远程服务器. 原文:Document Imag ...

  5. jquery显示和隐藏元素

    1.$('#id').show()/$('#id').hide()/$('#id').toggle() 2.$('#id').css('display','none')/$('#id').css('d ...

  6. Codeforces554E:Love Triangles

    There are many anime that are about "love triangles": Alice loves Bob, and Charlie loves B ...

  7. 微信小程序之 Swiper(轮播图)

    1.逻辑层 mine.js // pages/mine/mine.js Page({ /** * 页面的初始数据 */ data: { /*轮播图 配置*/ imgUrls: [ 'http://im ...

  8. 微信通过openID发送消息/后台post、get提交并接收数据 C# .NET 配置404,500等错误信息 连接字符串

    微信通过openID发送消息/后台post.get提交并接收数据   控制器:下面是post发送消息(微信不支持从前台发送数据,之前试过,报错,需要跨域,跨域的问题解决后还不行,最后发现之后后端提交 ...

  9. JavaScript语句-流程控制语句

    JavaScript定义了一组语句,语句通常用于执行一定的任务.语句可以很简单,也可以很复杂. 选择结构,可以在程序中创建交叉结构来指定程序流的可能方向.JavaScript中有四种选择结构: 1.单 ...

  10. 第一个get请求的爬虫程序

    一:urllib库: urllib是Python自带的一个用于爬虫的库,器主要作用就是可以通过代码模拟浏览器发送请求.其被用到子模块在Python3中的urllib.request和urllib.pa ...