题意

这题很难想到用莫队去做,因为第一印象是这个没办法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. How to: Calculate a Property Value Based on Values from a Detail Collection 如何:基于详细信息集合中的值计算属性值

    This topic describes how to implement a business class, so that one of its properties is calculated ...

  2. STM32-24位AD7799驱动之手册代码详解,支持模拟SPI和硬件SPI

    1.AD7799介绍 AD7799结构图如下所示: 其中REFIN参考电压建议为2.5V, REFIN电压低于0.1V时,则差分输入ad值就无法检测了,如下图所示: 注意: 如果REG_CONFIG的 ...

  3. 第03讲 fragment

    Fragment 官网文档:https://developer.android.google.cn/guide/components/fragments 什么是Fragment 在手机上,Activi ...

  4. git上传本地项目到github或者gitlib(两个是一样的)。

    第一步:在github上面创建一个repository   点击create就好了.然后会出现下面的页面. 第三步:打开你所在文件夹,或者是新建的文件夹(用来做仓库的)右键会出现下面  选用git B ...

  5. centos安装Redis和设置远程访问

    记录下步骤以后用到时翻一翻. 一.下载官方的文件包和编译 在centos下载依赖库: yum install gcc tcl 在redis官网的下载页面,这里可以选择离线包或在线下载. 我选择在线的, ...

  6. September 15th, 2019. Sunday, Week 38th.

    Break down these walls and come on in. 一路披荆斩棘,勇往直前. We are the only wall that stands in our way to s ...

  7. 07-Django视图进阶

    1.调试模式 Django项目下的settings.py 默认是DEBUG=True,开发的时候一般要开启调试模式,当项目完成发布必须要改成False,否则会暴露网站的配置信息,修改以下两行: # D ...

  8. 54. Spiral Matrix && 59. Spiral Matrix II

    Given a positive integer n, generate a square matrix filled with elements from 1 to n2 in spiral ord ...

  9. MySQL常用SQL语句总结

    1.with rollup 可以实现在分组统计数据基础上再进行相同的统计 SELECT name, SUM(score) as score_count FROM  score GROUP BY nam ...

  10. 多线程七 AQS

    一 . 简介AQS AQS简介 在同步组件的实现中,AQS是核心部分,同步组件的实现者,通过使用AQS提供的模板方法 实现同步组件语义 AQS实现了对同步状态的管理以及阻塞线程进行排队,等待通知等等一 ...