题目描述

给定长度为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. 团队作业8——测试与发布(Beta阶段)

    Deadline: 2017-12-17 23:00PM,以博客发表日期为准.   评分基准: 按时交 - 有分,检查的项目包括后文的三个方面 测试报告 发布说明 展示博客(单独一篇博客) 晚交 - ...

  2. 需求分析&原型改进

    需求&原型改进 一.给目标用户展现原型,与目标用户进一步沟通理解需求. 1.用户痛点:需要随时随地练习四则运算,并能看到用户的统计数据. 2.用户反馈:较好地解决练习需求,若能加入班级概念则更 ...

  3. iOS极光推送SDK的使用流程

    一.极光推送简介 极光推送是一个端到端的推送服务,使得服务器端消息能够及时地推送到终端用户手机上,整合了iOS.Android和WP平台的统一推送服务.使用起来方便简单,已于集成,解决了原生远程推送繁 ...

  4. XML使用练习

    #!/usr/bin/env python # -*- coding:utf-8 -*- import requests from xml.etree import ElementTree as ET ...

  5. 【iOS】swift init构造器

    这几天在使用 Swift 重写原来的一个运动社交应用 SportJoin. 为什么要重写呢? 首先因为实在找不到设计师给我作图; 其次, 我也闲不下来, 想找一些项目做, 所以只好将原来的代码重写了. ...

  6. linux 下 nc 命令的使用

    netcat被誉为网络安全界的'瑞士军刀',一个简单而有用的工具,透过使用TCP或UDP协议的网络连接去读写数据.它被设计成一个稳定的后门工具,能够直接由其它程序和脚本轻松驱动.同时,它也是一个功能强 ...

  7. JAVA_SE基础——65.StringBuffer类 ②

    字符串特点:字符串是常量:它们的值在创建之后不能更改.    字符串的内容一旦发生了变化,那么马上会创建一个新 的对象.    注意: 字符串的内容不适宜频繁修改,因为一旦修改马上就会创建一个新的对象 ...

  8. Python之旅_第一章Python入门

    一.编程语言分类 1.机器语言:即计算机能听懂的二进制语言,0000 0001,直接操控硬件: 2.汇编语言:简写的英文标识符代替二进制语言,本质同样是直接操控硬件: 3.高级语言:用更贴近人类的语言 ...

  9. GIT的安装及命令使用

    http://blog.jobbole.com/78960/ 因此:多人协作工作模式一般是这样的: 首先,可以试图用git push origin branch-name推送自己的修改. 如果推送失败 ...

  10. React中路由传参及接收参数的方式

    注意:  路由表改变后要重启服务      方式 一:          通过params         1.路由表中                     <Route path=' /s ...