做法同bzoj4262
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int gint(){
char c; int f=1;
while(c=getchar(),c<48||c>57)
if(c=='-')f=-1;
int x=0;
for(;c>47&&c<58;c=getchar()){
x=x*10+c-48;
}
return x*f;
}
#define max_N 100005
#define mod 1000000000
int n,A[max_N];
void init(){
int g1=1,g2=1;
for(int i=1;i<=n;++i){
g1=1ll*g1*1023%mod;
g2=1ll*g2*1025%mod;
A[i]=g1^g2;
}
}
struct QY{
int l,r,f,id,next;
QY(int l=0,int r=0,int f=0,int id=0,int n=0):l(l),r(r),f(f),id(id),next(n){}
}Q[max_N<<1];
int t,head[max_N],tot;
inline void add_QY(int x,int l,int r,int f,int id){
if(!x)return;
Q[++tot]=QY(l,r,f,id,head[x]),head[x]=tot;
}
typedef long long ll;
struct data{
ll v,s;
int t;
}T[max_N<<2];
inline data merge(const data&a,const data&b){
data res;
res.v=a.v+b.v;
res.t=max(a.t,b.t);
res.s=a.s+b.s+a.v*(res.t-a.t)+b.v*(res.t-b.t);
return res;
}
struct tags{
int a,tl,tr;
ll s;
}tag[max_N<<2];
inline void modify(data&x,const tags&y,int len){
x.s+=x.v*(y.tl-x.t)+y.s*len;
x.v=1ll*y.a*len;
x.t=y.tr;
}
inline void modify(tags&x,const tags&y){
if(x.a==-1){x=y; return;}
x.s+=1ll*x.a*(y.tl-x.tr)+y.s;
x.a=y.a,x.tr=y.tr;
}
inline void putdown(int x,int l,int m,int r){
if(tag[x].a==-1)return;
modify(T[x<<1],tag[x],m-l+1);
modify(tag[x<<1],tag[x]);
modify(T[x<<1|1],tag[x],r-m);
modify(tag[x<<1|1],tag[x]);
tag[x].a=-1;
}
#define lch x<<1,l,m
#define rch x<<1|1,m+1,r
void modify(int x,int l,int r,int ll,int rr,int a,int t){
if(ll<=l&&r<=rr){
tags y;
y.a=a,y.s=0,y.tl=y.tr=t;
modify(T[x],y,r-l+1);
modify(tag[x],y);
return;
}
int m=(l+r)>>1;
putdown(x,l,m,r);
if(ll<=m)modify(lch,ll,rr,a,t);
if(rr>m) modify(rch,ll,rr,a,t);
T[x]=merge(T[x<<1],T[x<<1|1]);
}
data query(int x,int l,int r,int ll,int rr){
if(l==ll&&r==rr)return T[x];
int m=(l+r)>>1;
putdown(x,l,m,r);
if(rr<=m)return query(lch,ll,rr);
if(ll>m) return query(rch,ll,rr);
return merge(query(lch,ll,m),query(rch,m+1,rr));
}
int st[max_N],top;
ll ans[max_N];
void Tree_init(int x,int l,int r){
T[x].v=T[x].s=T[x].t=0;
tag[x].a=-1;
if(l==r)return;
int m=(l+r)>>1;
Tree_init(x<<1,l,m);
Tree_init(x<<1|1,m+1,r);
}
int main(){
// freopen("input.txt","r",stdin);
n=gint(),t=gint();
for(int i=1;i<=n;++i)A[i]=gint();
for(int i=1,l,r;i<=t;++i){
l=gint(),r=gint();
add_QY(l-1,l,r,-1,i),add_QY(r,l,r,1,i);
}
Tree_init(1,1,n);
top=0;
for(int i=1;i<=n;++i){
while(top&&A[st[top]]>=A[i])--top;
modify(1,1,n,st[top]+1,i,A[i],i);
st[++top]=i;
for(int j=head[i];j;j=Q[j].next){
data tmp=query(1,1,n,Q[j].l,Q[j].r);
ans[Q[j].id]+=(tmp.s+tmp.v*(i-tmp.t+1))*Q[j].f;
}
}
for(int i=1;i<=t;++i){
printf("%lld\n",ans[i]);
}
return 0;
}