传送门


思路

看到可离线、无修改、区间询问,相信一定可以想到莫队。

然而,莫队怎么转移是个大问题。

考虑\([l,r]\rightarrow[l,r+1]\)时答案会怎样变化?(左端点变化时同理)

\(ans+=\sum_{i=l}^r \min\{a_i,a_{i+1} ,\dots ,a_r\}\)。

那么这东西如何快速统计呢?

考虑使用前缀和。

首先,显然要用单调栈预处理每个点左边最靠右的第一个比它小的数的位置\(L_i\),和ST表处理出RMQ的位置。

预处理出对于每一个\(r\),\(F(r)=\sum_{i=1}^r \min\{a_i,a_{i+1} ,\dots ,a_r\}\),方法如下:

\[F(r)=F(L_r)+a_r\times (r-L_r)
\]

上面公式的意思是:\((L_r,r]\)这一段带来的贡献是\(a_r\),其他就和\(a_r\)无关,可以用\(F(L_r)\)代替了。

然后,\([l,r-1]\rightarrow[l,r]\)时就有:

\[\Delta ans=F(r)-F(L_{pos})-a_{pos}\times (l-1-L_{pos})
\]

其中\(pos\)表示\([l,r]\)中最小值的位置。

于是就做完了。


代码

#include<bits/stdc++.h>
clock_t t=clock();
namespace my_std{
using namespace std;
#define pii pair<int,int>
#define fir first
#define sec second
#define MP make_pair
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define drep(i,x,y) for (int i=(x);i>=(y);i--)
#define go(x) for (int i=head[x];i;i=edge[i].nxt)
#define templ template<typename T>
#define sz 101100
typedef long long ll;
typedef double db;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
templ inline T rnd(T l,T r) {return uniform_int_distribution<T>(l,r)(rng);}
templ inline bool chkmax(T &x,T y){return x<y?x=y,1:0;}
templ inline bool chkmin(T &x,T y){return x>y?x=y,1:0;}
templ inline T min(T x,T y){return x<y?x:y;}
templ inline T max(T x,T y){return x>y?x:y;}
templ inline void read(T& t)
{
t=0;char f=0,ch=getchar();double d=0.1;
while(ch>'9'||ch<'0') f|=(ch=='-'),ch=getchar();
while(ch<='9'&&ch>='0') t=t*10+ch-48,ch=getchar();
if(ch=='.'){ch=getchar();while(ch<='9'&&ch>='0') t+=d*(ch^48),d*=0.1,ch=getchar();}
t=(f?-t:t);
}
template<typename T,typename... Args>inline void read(T& t,Args&... args){read(t); read(args...);}
void file()
{
#ifndef ONLINE_JUDGE
freopen("a.in","r",stdin);
#endif
}
inline void chktime()
{
#ifndef ONLINE_JUDGE
cout<<(clock()-t)/1000.0<<'\n';
#endif
}
#ifdef mod
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x%mod) if (y&1) ret=ret*x%mod;return ret;}
ll inv(ll x){return ksm(x,mod-2);}
#else
ll ksm(ll x,int y){ll ret=1;for (;y;y>>=1,x=x*x) if (y&1) ret=ret*x;return ret;}
#endif
// inline ll mul(ll a,ll b){ll d=(ll)(a*(double)b/mod+0.5);ll ret=a*b-d*mod;if (ret<0) ret+=mod;return ret;}
}
using namespace my_std; int n,m;
ll a[sz]; int L[sz],R[sz];
ll Fl[sz],Fr[sz];
int st[sz][23],lg2[sz];
#define cmp(x,y) ((a[x]<a[y])?(x):(y))
inline int query(int l,int r){int len=lg2[r-l+1];return cmp(st[l][len],st[r-(1<<len)+1][len]);}
void init()
{
rep(i,1,n) st[i][0]=i;
rep(i,2,n) lg2[i]=lg2[i>>1]+1;
rep(i,1,20)
rep(j,1,n-(1<<i)+1)
st[j][i]=cmp(st[j][i-1],st[j+(1<<(i-1))][i-1]);
stack<int>s;
rep(i,1,n)
{
while (!s.empty()&&a[s.top()]>=a[i]) s.pop();
L[i]=(s.empty()?0:s.top());
s.push(i);
}
while (!s.empty()) s.pop();
drep(i,n,1)
{
while (!s.empty()&&a[s.top()]>a[i]) s.pop();
R[i]=(s.empty()?n+1:s.top());
s.push(i);
}
rep(i,1,n) Fl[i]=a[i]*ll(i-L[i])+Fl[L[i]];
drep(i,n,1) Fr[i]=a[i]*ll(R[i]-i)+Fr[R[i]];
}
#undef cmp inline ll queryL(int l,int r) /* [l+1,r]->[l,r] */
{
int pos=query(l,r),Rpos=R[pos];
return Fr[l]-Fr[Rpos]-a[pos]*ll(Rpos-1-r);
}
inline ll queryR(int l,int r) /* [l,r-1]->[l,r] */
{
int pos=query(l,r),Lpos=L[pos];
return Fl[r]-Fl[Lpos]-a[pos]*ll(l-1-Lpos);
} int blo,pos[sz];
void Init(){blo=n/sqrt(m);rep(i,1,n) pos[i]=i/blo;}
struct hh{int l,r,id;}q[sz];
inline bool cmp(const hh &x,const hh &y){return pos[x.l]==pos[y.l]?((pos[x.l]&1)?x.r<y.r:x.r>y.r):pos[x.l]<pos[y.l];}
ll Ans[sz]; int main()
{
file();
read(n,m);
rep(i,1,n) read(a[i]);
int l,r;
rep(i,1,m) read(l,r),q[i]=(hh){l,r,i};
init();Init();sort(q+1,q+m+1,cmp);
ll ans=0;
int LL=1,RR=0;
rep(i,1,m)
{
int l=q[i].l,r=q[i].r;
while (LL>l) --LL,ans+=queryL(LL,RR);
while (RR<r)
++RR,ans+=queryR(LL,RR);
while (LL<l) ans-=queryL(LL,RR),++LL;
while (RR>r) ans-=queryR(LL,RR),--RR;
Ans[q[i].id]=ans;
}
rep(i,1,m) printf("%lld\n",Ans[i]);
return 0;
}

洛谷P3246 [HNOI2016]序列 [莫队]的更多相关文章

  1. 洛谷P3245 [HNOI2016]大数(莫队)

    题意 题目链接 Sol 莫队板子题.. 维护出每个位置开始的字符串\(mod P\)的结果,记为\(S_i\) 两个位置\(l, r\)满足条件当且仅当\(S_l - S_r = 0\),也就是\(S ...

  2. 洛谷 P3246 - [HNOI2016]序列(单调栈+前缀和)

    题面传送门 这道题为什么我就没想出来呢/kk 对于每组询问 \([l,r]\),我们首先求出区间 \([l,r]\) 中最小值的位置 \(x\),这个可以用 ST 表实现 \(\mathcal O(n ...

  3. 洛谷P3246 [HNOI2016]序列(离线 差分 树状数组)

    题意 题目链接 Sol 好像搞出了一个和题解不一样的做法(然而我考场上没写出来还是爆零0) 一个很显然的思路是考虑每个最小值的贡献. 预处理出每个数左边第一个比他小的数,右边第一个比他大的数. 那么\ ...

  4. 洛谷P3246 [HNOI2016]序列

    传送门 题解 //minamoto #include<iostream> #include<cstdio> #define ll long long using namespa ...

  5. [HNOI2016]序列(莫队,RMQ)

    [HNOI2016]序列(莫队,RMQ) 洛谷  bzoj 一眼看不出来怎么用数据结构维护 然后还没修改 所以考虑莫队 以$(l,r-1) -> (l,r)$为例 对答案的贡献是$\Sigma_ ...

  6. BZOJ.4540.[HNOI2016]序列(莫队/前缀和/线段树 单调栈 RMQ)

    BZOJ 洛谷 ST表的一二维顺序一定要改过来. 改了就rank1了哈哈哈哈.自带小常数没办法. \(Description\) 给定长为\(n\)的序列\(A_i\).\(q\)次询问,每次给定\( ...

  7. BZOj 4540: [Hnoi2016]序列 [莫队 st表 预处理]

    4540: [Hnoi2016]序列 题意:询问区间所有子串的最小值的和 不强制在线当然上莫队啦 但是没想出来,因为不知道该维护当前区间的什么信息,维护前后缀最小值的话不好做 想到单调栈求一下,但是对 ...

  8. bzoj 3236: 洛谷 P4396: [AHOI2013]作业 (莫队, 分块)

    题目传送门:洛谷P4396. 题意简述: 给定一个长度为\(n\)的数列.有\(m\)次询问,每次询问区间\([l,r]\)中数值在\([a,b]\)之间的数的个数,和数值在\([a,b]\)之间的不 ...

  9. [BZOJ4540][HNOI2016]序列 莫队

    4540: [Hnoi2016]序列 Time Limit: 20 Sec  Memory Limit: 512 MB Description 给定长度为n的序列:a1,a2,…,an,记为a[1:n ...

随机推荐

  1. LINQ to SQL 中 Concat、Union、Intersect、Except 方法的使用

    Ø  前言 LINQ to SQL 中需要对两个或多个数据集进行操作,比如:合并.取交集等,主要使用下面四个方法,这四个方法都是 System.Linq.IQueryable<out T> ...

  2. Python中json一点小知识

    import json dic={ "name":"杨林" } ret=json.dumps(dic,ensure_ascii=False) #因为json.d ...

  3. dbms_redefinition在线重定义表结构

    dbms_redefinition在线重定义表结构 (2013-08-29 22:52:58) 转载▼ 标签: dbms_redefinition 非分区表转换成分区表 王显伟 在线重定义表结构 在线 ...

  4. sqlserver 数据库插入汉字变成乱码的解决方案

     alter database 数据库名collate Chinese_PRC_CI_AS在英文版(或者其他版本)的数据库中插入中文会出现乱码这个就可以修改数据库排序规则.不会出现乱码了 

  5. remove() 方法

    jQuery的 remove() 方法,去掉选中元素. 例如: $("button").click(function(){ $("p").remove(); } ...

  6. CDH安装报错 Monitor-HostMonitor throttling_logger ERROR ntpq: ntpq -np: not synchronized to any server

    1 没有安装ntp同步服务 所有机器统一时区,确认所有机器配置一致  vim /etc/sysconfig/clock ntp服务器配置 ln -sf /usr/share/zoneinfo/Asia ...

  7. spring-core 中 asm 包的作用

    asm包中主要有以下这些类 其中, AnnotationVisitor类:是一个抽象类,定义在解析注解时会触发的事件,如解析到一个基本值类型的注解.enum值类型的注解.Array值类型的注解.注解值 ...

  8. 一个spring3.2的项目 从jdk1.7放到1.8的环境中编译,打开网页异常:spring jar包版本升级经历

    背景:一个历史项目用的是 spring3.2 的版本,在jdk1.7中运行没有问题,但是如果在jdk1.8中运行就会报错 ---浏览器中显示: HTTP Status 500 - Servlet.in ...

  9. Maven多模块项目管理小结

    原文地址:http://blog.csdn.net/whuslei/article/details/7989102 题记 最近刚完成一个用Maven构建的Web项目,看了一些Maven方面的书,比如& ...

  10. Light oj 1018 - Brush (IV) 状态压缩

    题目大意: 给出n个点的坐标,求至少画多少掉直线才能连接所有点. 题目思路:状态压缩 首先经行预处理,求出所有状态下,那些点不在该状态内 以任意两点为端点求出这条直线的状态 枚举所有状态,找出不在当前 ...