# SP22343 Norma--序列分治

## 题解

j < p 时 ( $$min*max$$ 不变) :

$ans+= min*max* \sum_{j=mid+1}^{p-1}(j-i+1)$

p<=j<q 时(只有 min 和区间长度发生改变):

$ans+= max * \sum_{j=p}^{q-1} min[j] * (j-i+1)$

--> $$ans+=max* \sum_{j=p}^{q-1} min[j] j+max * (1-i)\sum_{j=p}^{q-1} min[j])$$

q<j<=r 时(全都改变):

$ans+= \sum_{j=p}^{q-1} max[j]*min[j] * (j-i+1)$

--> $$ans+= \sum_{j=p}^{q-1} max[j]min[j] j+(1-i)\sum_{j=p}^{q-1} max[j]min[j])$$

#include<bits/stdc++.h>
using namespace std;
#define re register
#define in inline
#define get getchar()
#define ll long long
{
int t=0; char ch=get;
while(ch<'0' || ch>'9') ch=get;
while(ch<='9' && ch>='0') t=t*10+ch-'0', ch=get;
return t;
}
const int mod=1e9;
const int _=500002;
int n;
ll mul_mx[_],mul_mn[_],ans,sum_mx[_],sum_mn[_],mx[_],mn[_],a[_],mnmx[_],mul_mnmx[_];
in ll add(ll a,ll b) { //加法取模
return (((a%mod)+(b%mod))+mod)%mod;
}
in ll mul(ll a,ll b) { //乘法取模
return ((a%mod*b%mod)+mod)%mod;
}
in ll getsum(ll a,ll b) { //高斯求和
return ((a+b)*(b-a+1)/2)%mod;
}
in void work(int l,int r)
{
//	cout<<l<<' '<<r<<" :: "<<endl;
int mid=l+r>>1;
work(l,mid);
work(mid+1,r);
mx[mid]=mn[mid]=a[mid];
sum_mx[mid]=sum_mn[mid]=mul_mx[mid]=mul_mn[mid]=mul_mnmx[mid]=mnmx[mid]=0;
for(re int i=mid+1;i<=r;i++) {
mx[i]=max(mx[i-1],a[i]);
mn[i]=min(mn[i-1],a[i]);
} //预处理
ll maxx=0,minn=0x3f3f3f3f3f3f3f3f;
for(re int p=mid+1,q=mid+1,i=mid;i>=l;i--)
{
minn=min(minn,a[i]),maxx=max(maxx,a[i]);
while(p<=r&&minn<a[p]) p++;
while(q<=r&&maxx>a[q]) q++; //找到p和q
if(p<q)
{
} //套上之前讲的三个式子
else
{