洛谷P3246 序列 [HNOI2016] 莫队/线段树+扫描线
正解:莫队/线段树+扫描线
解题报告:
似乎是有两种方法的,,,所以分别港下好了QAQ
第一种,莫队
看到这种询问很多区间之类的就会自然而然地想到莫队趴?然后仔细思考一下,发现复杂度似乎是欧克的,而且好像也是能做的,那就试着做下呗
首先考虑到怎么从[l,r]转移到[l,r+1],可以想到这个之间的增量=就是区间内最小值之和,于是用个st表搞rmq就好,这里具体港下QwQ
首先如果已经求出来了[l,r]内部的最小值的位置pos,这里不过多阐述了rmq就成了
那么分情况讨论下咯
如果a[r+1]<a[pos],那就是贡献a[r+1]*(r-l+1),不说
否则就要继续讨论
显然[l,pos]的贡献就都出来了嘛,a[pos]*(pos-l+1)
然后考虑怎么求[pos+1,r]的贡献呢QAQ?
可以考虑开俩数组lst[i]表示第i个数的左边第一个比它小的数,可以先单调栈求出来
再设sum[i]表示第1个数到第i个数的贡献
显然可以得到sum[i]=sum[lst[i]]+a[i]*(i-lst[i])
然后就可以得到总贡献=a[pos]*(pos-l+1)+sum[r+1]-sum[pos]
然后如果是移动l就再搞个反的就成了,差不多
那接下来不就是莫队板子了嘛,不说了
#include<bits/stdc++.h>
using namespace std;
#define il inline
#define fr first
#define sc second
#define rg register
#define gc getchar()
#define mp make_pair
#define ll long long
#define rp(i,x,y) for(rg int i=x;i<=y;++i)
#define my(i,x,y) for(rg int i=x;i>=y;--i) const ll N=+;
int n,m,blk;
int l[N],r[N],s[N],top,a[N],lg[N],poww[N],l_nw,r_nw;
ll f[N],g[N],as[N],ret;
struct query{int i,l,r,blk;}q[N];
bool operator<(query a,query b){if(a.blk!=b.blk)return a.blk<b.blk;return a.r<b.r;}
struct stable
{
int p[][N];
il void pre(){rp(j,,lg[n])rp(i,,n-poww[j-])p[j][i]=a[p[j-][i]]<=a[p[j-][i+poww[j-]]]?p[j-][i]:p[j-][i+poww[j-]];}
il int query(int l,int r){int k=lg[r-l+];return a[p[k][l]]<=a[p[k][r-poww[k]+]]?p[k][l]:p[k][r-poww[k]+];}
}st; il int read()
{
rg char ch=gc;rg int x=;rg bool y=;
while(ch!='-' && (ch>'' || ch<''))ch=gc;
if(ch=='-')ch=gc,y=;
while(ch>='' && ch<='')x=(x<<)+(x<<)+(ch^''),ch=gc;
return y?x:-x;
}
il ll calcl(int l,int r){int pos=st.query(l,r);return 1ll*(r-pos+)*a[pos]+g[l]-g[pos];}
il ll calcr(int l,int r){int pos=st.query(l,r);return 1ll*(pos-l+)*a[pos]+f[r]-f[pos];}
il void pre(){poww[]=;poww[]=;lg[]=;rp(i,,n)poww[i]=poww[i-]<<,lg[i]=lg[i>>]+;} int main()
{
// freopen("xl.in","r",stdin);freopen("xl.out","w",stdout);
n=read();m=read();blk=sqrt(n);pre();
rp(i,,n)a[i]=read();
rp(i,,n){while(top&&a[s[top]]>a[i])--top;l[i]=s[top];s[++top]=i;}rp(i,,n)f[i]=f[l[i]]+1ll*(i-l[i])*a[i];
s[top=]=n+;
my(i,n,){while(top&&a[s[top]]>a[i])--top;r[i]=s[top];s[++top]=i;}my(i,n,)g[i]=g[r[i]]+1ll*(r[i]-i)*a[i];
rp(i,,n)st.p[][i]=i;st.pre();
rp(i,,m){int l=read(),r=read();q[i]=(query){i,l,r,(l-)/blk};}sort(q+,q++m);l_nw=q[].l;r_nw=l_nw-;
rp(i,,m)
{
while(r_nw<q[i].r)ret+=calcr(l_nw,++r_nw);
while(l_nw>q[i].l)ret+=calcl(--l_nw,r_nw);
while(r_nw>q[i].r)ret-=calcr(l_nw,r_nw--);
while(l_nw<q[i].l)ret-=calcl(l_nw++,r_nw);
as[q[i].i]=ret;
}
rp(i,,m)printf("%lld\n",as[i]);
return ;
}
然后放下代码w
第二种,线段树+扫描线
其实和影魔差不多来着,,,
所以为什么我麻油做出来呢QAQ
说明是真的落实很不扎实,很不应该
然后说下思路,,,我想了好久才get,,,真的还是要认真落实,,,不然吃枣药丸,,,
其实真的和影魔差不多了,,,只是一个要维护最大值一个要维护最小值来着QAQ
所以这题就一样的思路,考虑对栈维护一棵线段树,对整个儿序列维护一棵线段树
先放下我的浅薄理解QAQ
考虑for循环枚举右端点,然后每次对于右端点在当前枚举点的就可以直接求值了
然后现在是维护了一个单调栈嘛,不难想到对于每个子区间,答案可以分成两个部分
考虑找到单调栈中小于等于这个区间的右端点r的最大元素的位置i,对于单调栈中位置在i及其右边的点,贡献是一定的,就是∑a[stck[i]]*(stck[i]-stck[i-1]),而且这个显然是可以给栈开一个线段树维护的,就每次栈中加入新元素的时候说明当前点能延伸到的最右已经固定了(之后被弹走什么的一会儿另说QAQ),所以就可以对这个栈的线段树上加上这个值
但是对于i+1到r的值,如果另外求,复杂度依然过不去
考虑到在i到右端点本来也是有个最大值的,只是之后被栈中的i+1那个点给弹走了
所以我们可以在每个栈中元素被弹走的时候再维护另外一个线段树,这样就可以分别求出两个部分的ans,然后相加就好
大概就是酱婶儿的,然后等下放代码QAQ
洛谷P3246 序列 [HNOI2016] 莫队/线段树+扫描线的更多相关文章
- 洛谷P3245 大数 [HNOI2016] 莫队
正解:莫队 解题报告: 传送门 这题首先要发现一个结论,是这样儿的: 若p不是10的约数(即2和5) 时,当第i位到第n位组成的数%p==第j位到第n位组成的数%p,那么第i位到第j位上的数组成的数% ...
- 洛谷P4247 序列操作 [清华集训] 线段树
正解:线段树 解题报告: 传送门! 通过这题我get了一个神奇的,叫,线段树五问的东西hhhh 听起来有点中二但感觉真正做题的时候还是比较有用的,,,?感觉会让条理清晰很多呢,所以放一下QwQ →每个 ...
- Codeforces 666E E - Forensic Examination SA + 莫队 + 线段树
E - Forensic Examination 我也不知道为什么这个复杂度能过, 而且跑得还挺快, 数据比较水? 在sa上二分出上下界, 然后莫队 + 线段树维护区间众数. #include< ...
- bzoj 3236: 洛谷 P4396: [AHOI2013]作业 (莫队, 分块)
题目传送门:洛谷P4396. 题意简述: 给定一个长度为\(n\)的数列.有\(m\)次询问,每次询问区间\([l,r]\)中数值在\([a,b]\)之间的数的个数,和数值在\([a,b]\)之间的不 ...
- 洛谷 P4396 (离散化+莫队+树状数组)
### 洛谷P4396 题目链接 ### 题目大意: 有 n 个整数组成的数组,m 次询问,每次询问中有四个参数 l ,r,a,b .问你在[l,r] 的区间内的所有数中,值属于[a,b] 的数的个 ...
- 洛谷P4396 作业 [AHOI2013] 莫队
正解:莫队 解题报告: 传送门! 天呐太久没做莫队了连板子都认不出来了,,,所以复健下做下莫队的题目QAQ 就很板子鸭,和莫队板子比好像只有一个离散化,,,?就不讲了QAQ 等下直接放代码QAQ ov ...
- 洛谷 P2056 采花 - 莫队算法
萧芸斓是 Z国的公主,平时的一大爱好是采花. 今天天气晴朗,阳光明媚,公主清晨便去了皇宫中新建的花园采花.花园足够大,容纳了 n 朵花,花有 c 种颜色(用整数 1-c 表示) ,且花是排成一排的,以 ...
- 洛谷P3928 Sequence2(dp,线段树)
题目链接: 洛谷 题目大意在描述底下有.此处不赘述. 明显是个类似于LIS的dp. 令 $dp[i][j]$ 表示: $j=1$ 时表示已经处理了 $i$ 个数,上一个选的数来自序列 $A[0]$ 的 ...
- 【CF633H】Fibonacci-ish II 莫队+线段树
[CF633H]Fibonacci-ish II 题意:给你一个长度为n的序列$a_i$.m个询问,每个询问形如l,r:将[l,r]中的所有$a_i$排序并去重,设得到的新数列为$b_i$,求$b_1 ...
随机推荐
- 解决:android源码同步repo sync 时出现的fatal:duplicate path错误
问题重现: 解决方法: 1.删除android项目里隐藏的 .repo 文件夹中除了以下几个文件夹的其他文件及文件夹 2.重新初始化android项目 repo init -u https//gith ...
- hadoop 在centos中的搭建
总体思路,准备主从服务器,配置主服务器可以无密码SSH登录从服务器,解压安装JDK,解压安装Hadoop,配置hdfs.mapreduce等主从关系. 1.环境,3台CentOS7,64位,Hadoo ...
- mysql的text字段长度?mysql数据库中text字段长度不够的问题
类型是可变长度的字符串,最多65535个字符: 可以把字段类型改成MEDIUMTEXT(最多存放16777215个字符)或者LONGTEXT(最多存放4294967295个字符). MySQL ...
- ABBYY OCR技术教电脑阅读缅甸语(下)
文本行检测到之后,我们开始寻找单词和字母之间的间隙,这一次,我们运用了水平直方图,将大的间隙假设为单词之间的空隙,小的间隙理解为字母之间的空隙,检测缅甸文本中的空隙几乎没有出现问题,不像泰语,几乎没有 ...
- jexl2 执行字符串Java代码
一,引入jar包, <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-jexl --><depen ...
- [IR] Search Server - Sphinx
使用 Sphinx 更好地进行 MySQL 搜索 - IBM 尽管 MySQL 是一个出色的通用数据库,但是如果您的应用程序需要进行大量搜索,那么使用 Sphinx 可获得更好的性能. 尽管 Sphi ...
- 百度网盘上下载文件,调用api接口的请求方式和参数
REST api 功能:下载单个文件. Download接口支持HTTP协议标准range定义,通过指定range的取值可以实现断点下载功能. 例如: 如果在request消息中指定“Range: b ...
- 6 CLR静态构造器
CLR保证一个类型构造器在每个AppDomain中只执行一次,而且这种执行是线程安全的. 作用: 就是初始化静态成员 比如有几个静态成员需要初始化那你把初始化代码放到哪呢? 放到普通构造函数里,那肯定 ...
- nginx 动静分离(相同URL)
#报表 location ~* /(report)/ { if ($request_uri !~* .*(jd|taobao|operator).* ){ proxy_pass http://tweb ...
- Flask web开发之路十二
ge请求和post请求 ### get请求和post请求:1. get请求: * 使用场景:如果只对服务器获取数据,并没有对服务器产生任何影响,那么这时候使用get请求. * 传参:get请求传参是放 ...