题意

这题很难想到用莫队去做,因为第一印象是这个没办法O(1)移动指针。

考虑从\([l,r]\)移动到\([l,r+1]\) (从\([l,r]\)移动到\([l-1,r]\)同理)。

我们用ST表\(O(1)\)找到\([l,r+1]\)的最小值的位置\(mid\),考虑新加入的r+1会产生哪些贡献:显然是很多以\(r+1\)为右端点的子序列的最小值之和。

对于左端点分类讨论:

左端点在\([l,mid]\):这里的子序列最小值都为\(a[mid]\),因此贡献为\((mid-l+1)*a[mid]\)。

左端点在\([mid+1,r+1]\):这个似乎没法处理。

于是要考虑左端点在\([mid+1,r+1]\)如何处理:

正解是用前缀和处理的,很难想到。

\(R[i]\)表示\([1,i]\)这段区间的答案,\(pre[i]\)表示\(i\)左边第一个比它小的数的位置,那么就会有:

\(R_i=R_{pre_i}+(i-pre_i)*a_i\)

发现对于左端点在\([mid+1,r+1]\)的是可以用前缀和相减的:

\(R[r+1]-R[mid]\)。

至于为什么左端点在\([l,mid]\)不能用前缀和相减,主要是\(R[i]\)不一定从\(pre[i]\)转移,因为有\(l\)的限制。

其他同理。

注意个细节

code:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=100010;
int n,m,t,top,nowl,nowr;
int pre[maxn],nxt[maxn],pos[maxn];
ll nowans;
ll a[maxn],s[maxn],ans[maxn],L[maxn],R[maxn];
ll f[maxn][20];
struct Query
{
int l,r,id;
}qr[maxn];
inline bool cmp(Query x,Query y){return pos[x.l]==pos[y.l]?x.r<y.r:pos[x.l]<pos[y.l];}
inline void ST()
{
for(int i=1;i<=n;i++)f[i][0]=i;
for(int j=1;j<=18;j++)
for(int i=1;i+(1<<j)-1<=n;i++)
f[i][j]=a[f[i][j-1]]<a[f[i+(1<<(j-1))][j-1]]?f[i][j-1]:f[i+(1<<(j-1))][j-1];
}
inline int query(int l,int r)
{
int t=(int)log2(r-l+1);
return a[f[l][t]]<a[f[r-(1<<t)+1][t]]?f[l][t]:f[r-(1<<t)+1][t];
}
inline void addl(int x,int k)
{
//if(nowl>nowr)puts("!!!");
//printf("nowl::%d nowr::%d x::%d\n",nowl,nowr,x);
int mid=query(nowl,nowr);
//printf("%d %d %d\n",nowl,nowr,a[mid]);
nowans+=1LL*(L[x]-L[mid]+1LL*(nowr-mid+1)*a[mid])*k;
}
inline void addr(int x,int k)
{
//if(nowl>nowr)puts("!!!");
//printf("nowl::%d nowr::%d x::%d\n",nowl,nowr,x);
int mid=query(nowl,nowr);
//printf("%d %d %d\n",nowl,nowr,a[mid]);
nowans+=1LL*(R[x]-R[mid]+1LL*(mid-nowl+1)*a[mid])*k;
}
signed main()
{
//freopen("test.in","r",stdin);
//freopen("test.out","w",stdout);
scanf("%d%d",&n,&m);t=sqrt(n);a[0]=844828908;
for(int i=1;i<=n;i++)scanf("%lld",&a[i]),pos[i]=(i-1)/t+1;
for(int i=1;i<=m;i++)scanf("%d%d",&qr[i].l,&qr[i].r),qr[i].id=i;
sort(qr+1,qr+m+1,cmp);
ST();
for(int i=1;i<=n;i++)
{
while(top&&a[s[top]]>a[i])nxt[s[top]]=i,top--;
pre[i]=s[top];s[++top]=i;
}
for(int i=1;i<=top;i++)nxt[s[i]]=n+1;
for(int i=1;i<=n;i++)R[i]=R[pre[i]]+1LL*a[i]*(i-pre[i]);
for(int i=n;i;i--)L[i]=L[nxt[i]]+1LL*a[i]*(nxt[i]-i);
nowans=a[nowl=nowr=1];
//for(int i=1;i<=n;i++)printf("%lld ",pos[i]);
//puts("");
for(int i=1;i<=m;i++)
{
while(nowr<qr[i].r)nowr++,addr(nowr,1);
while(nowl>qr[i].l)nowl--,addl(nowl,1);
while(nowr>qr[i].r)addr(nowr,-1),nowr--;
while(nowl<qr[i].l)addl(nowl,-1),nowl++;
ans[qr[i].id]=nowans;
}
for(int i=1;i<=m;i++)printf("%lld\n",ans[i]);
return 0;
}

luoguP3246 [HNOI2016]序列的更多相关文章

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

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

  2. 【LG3246】[HNOI2016]序列

    [LG3246][HNOI2016]序列 题面 洛谷 题解 60pts 对于每个位置\(i\),单调栈维护它往左第一个小于等于它的位置\(lp_i\)以及往右第一个小于它的位置\(rp_i\). 那么 ...

  3. 4540: [Hnoi2016]序列

    4540: [Hnoi2016]序列 https://www.lydsy.com/JudgeOnline/problem.php?id=4540 分析: 莫队+RMQ+单调栈. 考虑加入一个点后,区间 ...

  4. [BZOJ4540][HNOI2016]序列 莫队

    4540: [Hnoi2016]序列 Time Limit: 20 Sec  Memory Limit: 512 MB Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n ...

  5. BZOJ4540 Hnoi2016 序列 【莫队+RMQ+单调栈预处理】*

    BZOJ4540 Hnoi2016 序列 Description 给定长度为n的序列:a1,a2,-,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,-,ar- ...

  6. 【BZOJ4540】[Hnoi2016]序列 莫队算法+单调栈

    [BZOJ4540][Hnoi2016]序列 Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n].类似地,a[l:r](1≤l≤r≤N)是指序列:al,al+1,…,a ...

  7. [Bzoj4540][Hnoi2016] 序列(莫队 + ST表 + 单调队列)

    4540: [Hnoi2016]序列 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 1567  Solved: 718[Submit][Status] ...

  8. [HNOI2016]序列 CDQ+DP

    [HNOI2016]序列 CDQ 链接 loj 思路 一个点最小变为l,最大变为r,不变的时候为v 那么j能在i前面就要满足. \(j<i\) \(r[j]<=v[i]\) \(v[j]& ...

  9. 题解-[HNOI2016]序列

    题解-[HNOI2016]序列 [HNOI2016]序列 给定 \(n\) 和 \(m\) 以及序列 \(a\{n\}\).有 \(m\) 次询问,每次给定区间 \([l,r]\in[1,n]\),求 ...

随机推荐

  1. 一文理解Java IO/NIO/AIO

      目录 概述 一.IO流(同步.阻塞) 二.NIO(同步.非阻塞) 三.NIO2(异步.非阻塞) 正文 概述 在我们学习Java的IO流之前,我们都要了解几个关键词 同步与异步(synchronou ...

  2. 龙芯(mips64)电脑安装NodeJS

    背景 龙芯是国产的cpu,采用是mips架构,就类似大家熟知的x86.arm. 最近在一台龙芯电脑(系统是中兴新支点,Linux)上调试前端应用(electron),于是就需要安装NodeJS. 但是 ...

  3. SQLyog连接MySQL8.0报2058错误的解决方案

    引言 用SQLyog连接MySQL8.0(社区版:mysql-installer-community-8.0.15.0.msi),出现错误2058(Plugin caching_sha2_passwo ...

  4. Dynamics CRM通过定制应用程序功能区为符合条件的实体表单增加按钮

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复167或者20151029可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me! 前面的博文都是为一个实体添加按钮 ...

  5. HIFIMAN TWS600A听感小记——测评出街Man

    HIFIMAN TWS600A听感小记——测评出街Man 几年前蓝牙耳塞在大哥苹果的带领下有着掀翻小池塘的气势.蓝牙耳塞完全替代了我在通勤路上用的有线塞子,当时随便买了一副两百多元的塞子,低音轰头就算 ...

  6. MySQL数据库~~~~~锁和事务

    一 锁 innodb存储引擎默认是行级锁 行级锁定最大的特点就是锁定对象的颗粒度很小,也是目前各大数据库管理软件所实现的锁定颗粒度最小的.由于锁定颗粒度很小,所以发生锁定资源争用的概率也最小,能够给予 ...

  7. 好程序员web前端分享前端学习路线自学如何找到工作

    好程序员web前端分享前端学习路线自学如何找到工作,自学能不能学会WEB前端并且找到WEB前端开发岗位的工作取决于自身条件,如果基础好,自律性强那么将会容易很多,还有就是自学最难克服的并不是知识点,而 ...

  8. Linux目录详解,软件应该安装到哪个目录

    原文地址:https://www.w3h5.com/post/336.html 我们应该知道 Windows 有一个默认的安装目录专门用来安装软件.Linux 的软件安装目录也应该是有讲究的,遵循这一 ...

  9. Tyvj 1953 Normal:多项式,点分治

    Decription: 某天WJMZBMR学习了一个神奇的算法:树的点分治! 这个算法的核心是这样的: 消耗时间=0 Solve(树 a) 消耗时间 += a 的 大小 如果 a 中 只有 1 个点, ...

  10. 一文了解 Consistent Hash

    本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/LGLqEOlGExKob8xEXXWckQ作者:钱幸川 在分布式环境下面,我们经常会通过一定的 ...