题目描述

给定长度为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。

输入输出格式

输入格式:

输入文件的第一行包含两个整数n和q,分别代表序列长度和询问数。接下来一行,包含n个整数,以空格隔开,第i个整数为ai,即序列第i个元素的值。接下来q行,每行包含两个整数l和r,代表一次询问。

输出格式:

对于每次询问,输出一行,代表询问的答案。

输入输出样例

输入样例#1:

5 5
5 2 4 1 3
1 5
1 3
2 4
3 5
2 5
输出样例#1:

28
17
11
11
17

说明

1 <=N,Q <= 100000,|Ai| <= 10^9

网上给出的大多是两种:莫队和线段树+矩阵

可惜我这个菜鸡看不懂

这里给出一种近似暴力的方法

我们模仿影魔的线段树解法:

离线,把询问按l从小到大

R[i]表示i右边第一个比它小的位置

显然子序列[i,i~R[i]-1]的答案都是a[i],维护一个线段树,给i~R[i]-1加上a[i]

我们从n开始从后往前计算,当有询问左端点在i时

求出1~右端点的和

但是我们没有考虑i与R[i]之后的解,而且R[i]这样显然只会与在他后面形成子序列

所以递归把子序列[i,R[i]~R[R[i]]-1].......都加上a[R[i]]

但是这样如果碰到有序递减的序列会变成O(n^2logn)

但是这种省选题数据大多是随机的,所以可以过

有时间会补上莫队做法

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct Ask
{
int l;int r;int id;
}ask[];
long long c[],mark[],ans[],a[],aa[];
int n,q,stack[],R[],flag;
bool cmp(Ask a,Ask b)
{
return a.l<b.l;
}
void pushup(int rt)
{
c[rt]=c[rt*]+c[rt*+];
}
void pushdown(int rt,int l,int r,int mid)
{
if (mark[rt])
{
mark[rt*]+=mark[rt];
mark[rt*+]+=mark[rt];
c[rt*]+=mark[rt]*(mid-l+);
c[rt*+]+=mark[rt]*(r-mid);
mark[rt]=;
}
}
void change(int rt,int l,int r,int L,int R,long long d)
{
if (l>=L&&r<=R)
{
mark[rt]+=d;
c[rt]+=(r-l+)*d;
return;
}
pushdown(rt,l,r,(l+r)/);
int mid=(l+r)/;
if (L<=mid) change(rt*,l,mid,L,R,d);
if (R>mid) change(rt*+,mid+,r,L,R,d);
pushup(rt);
}
long long getsum(int rt,int l,int r,int L,int R)
{
if (l>=L&&r<=R)
{
return c[rt];
}
int mid=(l+r)/;
pushdown(rt,l,r,mid);
long long s=;
if (L<=mid) s+=getsum(rt*,l,mid,L,R);
if (R>mid) s+=getsum(rt*+,mid+,r,L,R);
pushup(rt);
return s;
}
void rev()
{int i;
for (i=;i<=n;i++)
aa[i]=a[n-i+];
for (i=;i<=n;i++)
a[i]=aa[i];
}
void zyys(int x)
{
while (x<=n-)
{
int l=x,r=R[x]-;
change(,,n,l,r,a[l]);
x=R[x];
}
}
void work()
{int top,i;
memset(c,,sizeof(c));
memset(mark,,sizeof(mark));
sort(ask+,ask+q+,cmp);
top=,stack[top]=n+;
for (i=n;i>=;i--)
{
while (top&&a[i]<a[stack[top]]) top--;
R[i]=stack[top];
stack[++top]=i;
}
n++;
top=q;
for (i=n;i>=;i--)
{
zyys(i);
while (top&&i==ask[top].l) ans[ask[top].id]+=getsum(,,n,,ask[top].r),top--;
}
}
int main()
{int i;
cin>>n>>q;
for (i=;i<=n;i++)
{
scanf("%lld",&a[i]);
}
for (i=;i<=q;i++)
{
scanf("%d%d",&ask[i].l,&ask[i].r);
ask[i].id=i;
}
work();
for (i=;i<=q;i++)
printf("%lld\n",ans[i]);
}

[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]\),求 ...

  10. P6604 [HNOI2016]序列 加强版

    *I. P6604 [HNOI2016]序列 加强版 摘自学习笔记 简单树论 笛卡尔树部分例题 I. 和 P6503 比较类似.我们设 \(f_i\) 表示全局以 \(i\) 结尾的子区间的最小值之和 ...

随机推荐

  1. 《团队-Android手机便签-项目进度》

    首先想提个小意见,结对编程那边还有些问题需要处理,这个时候就催团队进度是不是不太好,至少应该让我们把结对处理完是吧.但是作业终究是作业,布置了就得做,我们只得匆匆忙忙画了个界面,功能什么的根本没来得及 ...

  2. 微信号的openid的深入理解

    header('Location:https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->appid.'&r ...

  3. Django REST framework+Vue 打造生鲜超市(一)

    一.项目介绍 1.1.掌握的技术 Vue + Django Rest Framework 前后端分离技术 彻底玩转restful api 开发流程 Django Rest Framework 的功能实 ...

  4. LxmlLinkExtractor类参数解析

    LxmlLinkExtractor LxmlLinkExtractor 是一种强大的链接提取器,使用他能很方便的进行选项过滤,他是通过xml中强大的HTMLParser实现的 源代码如下: class ...

  5. 新概念英语(1-139)Is that you, John?

    Lesson 139 Is that you, John? 是你吗,约翰? Listen to the tape then answer this question. Which John Smith ...

  6. javascript学习(4)异常处理 try-catch 和 onerror

    一.try-catch 1.样例1 1.1.源代码 1.2.执行后 2.样例2 2.1.源代码 2.2.执行后 二.onerror 1.源代码 2.执行后

  7. GIT入门笔记(11)- 多种撤销修改场景和对策--实战练习

    1.检查发现目前没有变化$ git statusOn branch masternothing to commit, working tree clean $ cat lsq.txt2222 2.修改 ...

  8. mysql中独立表空间与共享表空间之前如何切换

    环境 mysql版本:5.7.19 官方文档:(https://dev.mysql.com/doc/refman/5.7/en/innodb-multiple-tablespaces.html) 查看 ...

  9. 理解JavaScript中的call和apply方法

    call方法 总的来说call()有这几种作用:1.可以借用另一个对象的方法.2.改变this的指向(重要).3.将arguments数组化.下面详细介绍这三种作用: 1.可以借用另一个对象的方法:当 ...

  10. Java中对List去重, Stream去重

    问题 当下互联网技术成熟,越来越多的趋向去中心化.分布式.流计算,使得很多以前在数据库侧做的事情放到了Java端.今天有人问道,如果数据库字段没有索引,那么应该如何根据该字段去重?大家都一致认为用Ja ...