1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
|
#include<bits/stdc++.h>
#define ll long long
#define mid ((l+r)>>1)
using namespace std;
const int N=5e5+3,p=1e9;
struct Val{
int sa,sb,sm;
Val(){sa=sb=sm=0;}
};
Val operator+(Val x,Val y){
Val z;
z.sa=(x.sa+y.sa)%p;
z.sb=(x.sb+y.sb)%p;
z.sm=(x.sm+y.sm)%p;
return z;
}
struct node{
int tga=-1,tgb=-1;
Val v;
void val(int ta,int tb,int l,int r){
if(~ta){
tga=ta;
v.sa=(ta*1LL*(r-l+1))%p;
v.sm=(ta*1LL*v.sb)%p;
}
if(~tb){
tgb=tb;
v.sb=(tb*1LL*(r-l+1))%p;
v.sm=(tb*1LL*v.sa)%p;
}
}
}tr[(N<<2)];
void push_down(int x,int l,int r){
tr[x<<1].val(tr[x].tga,tr[x].tgb,l,mid);
tr[x<<1|1].val(tr[x].tga,tr[x].tgb,mid+1,r);
tr[x].tga=tr[x].tgb=-1;
}
void push_up(int x)
{tr[x].v=tr[x<<1].v+tr[x<<1|1].v;}
void change(int x,int l,int r,int ql,int qr,int ta,int tb){
if(l>=ql&&r<=qr){tr[x].val(ta,tb,l,r);return;}
if(l>qr||r<ql) return;
push_down(x,l,r);
change(x<<1,l,mid,ql,qr,ta,tb),
change(x<<1|1,mid+1,r,ql,qr,ta,tb);
push_up(x);
}
Val ask(int x,int l,int r,int ql,int qr){
if(l>=ql&&r<=qr) return tr[x].v;
if(l>qr||r<ql) return Val();
push_down(x,l,r);
return ask(x<<1,l,mid,l,r)+ask(x<<1|1,mid+1,r,l,r);
}
int a[N],n;
ll ans=0;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
stack<int>mn,mx;
for(int i=1;i<=n;i++){
while(mx.size()&&a[mx.top()]<a[i]) mx.pop();
if(mx.size()) change(1,1,n,mx.top()+1,i,a[i],-1);
else change(1,1,n,1,i,a[i],-1);
mx.push(i);
while(mn.size()&&a[mn.top()]>a[i]) mn.pop();
if(mn.size()) change(1,1,n,mn.top()+1,i,-1,a[i]);
else change(1,1,n,1,i,-1,a[i]);
mn.push(i);
auto v=ask(1,1,n,1,i);
ans=(ans+(v.sm*1LL*(i+1))%p)%p;
}
while(mn.size()) mn.pop();
while(mx.size()) mx.pop();
change(1,1,n,1,n,0,0);
for(int i=n;i>=1;i--){
while(mx.size()&&a[mx.top()]<a[i]) mx.pop();
if(mx.size()) change(1,1,n,i,mx.top()-1,a[i],-1);
else change(1,1,n,i,n,a[i],-1);
mx.push(i);
while(mn.size()&&a[mn.top()]>a[i]) mn.pop();
if(mn.size()) change(1,1,n,i,mn.top()-1,-1,a[i]);
else change(1,1,n,i,n,-1,a[i]);
mn.push(i);
auto v=ask(1,1,n,i,n);
ans=(ans-(v.sm*1LL*i)%p)%p;
}
cout<<(ans%p+p)%p;
}
|