题目描述

给定长度为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. ord在python是什么意思?

    >>> help(ord)Help on built-in function ord in module builtins:ord(...) #这是一个函数 ord(c) -> ...

  2. python 继承基础

    class annamal: def chi(self): print(self.name + '吃') def he(self): print(self.name + '喝') class dog( ...

  3. 【iOS】swift 让程序挂起后,能在后台继续运行任务

    1,程序的挂起和退出 由于iOS设备资源有限.当用户点击了home键,或者另一个应用程序启动了.那么原先那个程序便进入后台被挂起,不是退出,只是停止执行代码,同时它的内存被锁定.当应用程序恢复时,它会 ...

  4. Django-rest-framework源码分析----认证

    一.前言 1.1.安装 两种方式: github pip直接安装 pip install django-rest-framework 1.2.需要先了解的一些知识 理解下面两个知识点非常重要,djan ...

  5. Class-Based-View(CBV)

    我们都知道,Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承.封装.多态).所以Django在后来加入了Class-Based-View.可以让我们用类写V ...

  6. 阿里云API网关(2)开放 API 并接入 API 网关

    网关指南: https://help.aliyun.com/document_detail/29487.html?spm=5176.doc48835.6.550.23Oqbl 网关控制台: https ...

  7. javascript实现继承3种方式: 原型继承、借用构造函数继承、组合继承,模拟extends方法继承

    javascript中实现继承的三种方式:原型继承.借用构造函数继承.混合继承: /* js当中的继承 js中 构造函数 原型对象 实力对象的关系: 1 构造函数.prototype = 原型对象 2 ...

  8. MongoDB系列四(索引).

    一.索引简介 再来老生常谈一番,什么是索引呢?数据库索引与书籍的索引类似.有了索引就不需要翻整本书,数据库可以直接在索引中查找,在索引中找到条目以后,就可以直接跳转到目标文档的位置,这能使查找速度提高 ...

  9. Python之格式化输出,初始编码以及运算符

    一.题型 1.使用while循环输入 1 2 3 4 5 6  8 9 10 count = 0 while count < 10: count += 1   #count = count + ...

  10. RxJava系列3(转换操作符)

    RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...