我觉得这就是个大暴力好吧但是还是比正解跑得快。
首先我们看到形如三个\(Max-Min\)相乘的形式。
这个显然可以拆成8个式子然后分开计算。
这里以三个max相乘为例表明怎么分治计算。
对于没有跨立区间中点的询问,我们递归计算。
对于跨过区间中点的区间,我们对于每个序列双指针出右边对应的前缀max分界点在哪里,然后分类讨论三个序列指针位置关系维护A,B,C,AB,AC,BC,ABC前缀和即可。
时间复杂度\(O(8nlogn)\)但是比std的\(O(6nlogn)\)跑得还快。
code:
#include<bits/stdc++.h>
#define I inline
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define abs(x) ((x)>0?(x):-(x))
#define re register
#define ll long long
#define db double
#define U unsigned int
#define N 100000
#define M 30
#define mod 19260817
#define eps (1e-7)
#define it iterator
#define Gc() getchar()
#define Me(x,y) memset(x,y,sizeof(x))
using namespace std;
int n,m,k;U ans1,ans2,ans3,ans4,A[N+5],B[N+5],C[N+5],QA[N+5],QB[N+5],QC[N+5],SumA[N+5],SumB[N+5],SumC[N+5],SumAB[N+5],SumAC[N+5],SumBC[N+5],SumABC[N+5],ar,br,cr;
I void swap(U &x,U &y){x^=y^=x^=y;}
I void Solve1(int l,int r,U &ans){
if(l==r) return (void)(ans+=A[l]*B[l]*C[l]);re int m=l+r>>1,i;Solve1(l,m,ans);Solve1(m+1,r,ans);
QA[m+1]=A[m+1];QB[m+1]=B[m+1];QC[m+1]=C[m+1];for(i=m+2;i<=r;i++)QA[i]=max(QA[i-1],A[i]),QB[i]=max(QB[i-1],B[i]),QC[i]=max(QC[i-1],C[i]);
QA[m]=A[m];QB[m]=B[m];QC[m]=C[m];for(i=m-1;i>=l;i--)QA[i]=max(QA[i+1],A[i]),QB[i]=max(QB[i+1],B[i]),QC[i]=max(QC[i+1],C[i]);
SumA[m]=SumB[m]=SumC[m]=SumAB[m]=SumAC[m]=SumBC[m]=SumABC[m]=0;
for(i=m+1;i<=r;i++) SumA[i]=SumA[i-1]+QA[i],SumB[i]=SumB[i-1]+QB[i],SumC[i]=SumC[i-1]+QC[i],SumAB[i]=SumAB[i-1]+QA[i]*QB[i],SumAC[i]=SumAC[i-1]+QA[i]*QC[i],SumBC[i]=SumBC[i-1]+QB[i]*QC[i],SumABC[i]=SumABC[i-1]+QA[i]*QB[i]*QC[i];
ar=br=cr=m+1;for(i=m;i>=l;i--){
while(ar<=r&&QA[ar]<=QA[i]) ar++;while(br<=r&&QB[br]<=QB[i]) br++;while(cr<=r&&QC[cr]<=QC[i]) cr++;
if(ar<=min(br,cr)){
ans+=QA[i]*QB[i]*QC[i]*(ar-m-1)+SumABC[r];
if(br<=cr)ans+=(SumA[br-1]-SumA[ar-1])*QB[i]*QC[i]+(SumAB[cr-1]-SumAB[br-1])*QC[i]-SumABC[cr-1];
else ans+=(SumA[cr-1]-SumA[ar-1])*QB[i]*QC[i]+(SumAC[br-1]-SumAC[cr-1])*QB[i]-SumABC[br-1];
}
else if(br<=min(ar,cr)){
ans+=QA[i]*QB[i]*QC[i]*(br-m-1)+SumABC[r];
if(ar<=cr)ans+=(SumB[ar-1]-SumB[br-1])*QA[i]*QC[i]+(SumAB[cr-1]-SumAB[ar-1])*QC[i]-SumABC[cr-1];
else ans+=(SumB[cr-1]-SumB[br-1])*QA[i]*QC[i]+(SumBC[ar-1]-SumBC[cr-1])*QA[i]-SumABC[ar-1];
}
else {
ans+=QA[i]*QB[i]*QC[i]*(cr-m-1)+SumABC[r];
if(ar<=br)ans+=(SumC[ar-1]-SumC[cr-1])*QA[i]*QB[i]+(SumAC[br-1]-SumAC[ar-1])*QB[i]-SumABC[br-1];
else ans+=(SumC[br-1]-SumC[cr-1])*QA[i]*QB[i]+(SumBC[ar-1]-SumBC[br-1])*QA[i]-SumABC[ar-1];
}
}
}
I void Solve2(int l,int r,U &ans){
if(l==r) return (void)(ans+=A[l]*B[l]*C[l]);re int m=l+r>>1,i;Solve2(l,m,ans);Solve2(m+1,r,ans);
QA[m+1]=A[m+1];QB[m+1]=B[m+1];QC[m+1]=C[m+1];for(i=m+2;i<=r;i++)QA[i]=min(QA[i-1],A[i]),QB[i]=max(QB[i-1],B[i]),QC[i]=max(QC[i-1],C[i]);
QA[m]=A[m];QB[m]=B[m];QC[m]=C[m];for(i=m-1;i>=l;i--)QA[i]=min(QA[i+1],A[i]),QB[i]=max(QB[i+1],B[i]),QC[i]=max(QC[i+1],C[i]);
SumA[m]=SumB[m]=SumC[m]=SumAB[m]=SumAC[m]=SumBC[m]=SumABC[m]=0;
for(i=m+1;i<=r;i++) SumA[i]=SumA[i-1]+QA[i],SumB[i]=SumB[i-1]+QB[i],SumC[i]=SumC[i-1]+QC[i],SumAB[i]=SumAB[i-1]+QA[i]*QB[i],SumAC[i]=SumAC[i-1]+QA[i]*QC[i],SumBC[i]=SumBC[i-1]+QB[i]*QC[i],SumABC[i]=SumABC[i-1]+QA[i]*QB[i]*QC[i];
ar=br=cr=m+1;for(i=m;i>=l;i--){
while(ar<=r&&QA[ar]>=QA[i]) ar++;while(br<=r&&QB[br]<=QB[i]) br++;while(cr<=r&&QC[cr]<=QC[i]) cr++;
if(ar<=min(br,cr)){
ans+=QA[i]*QB[i]*QC[i]*(ar-m-1)+SumABC[r];
if(br<=cr)ans+=(SumA[br-1]-SumA[ar-1])*QB[i]*QC[i]+(SumAB[cr-1]-SumAB[br-1])*QC[i]-SumABC[cr-1];
else ans+=(SumA[cr-1]-SumA[ar-1])*QB[i]*QC[i]+(SumAC[br-1]-SumAC[cr-1])*QB[i]-SumABC[br-1];
}
else if(br<=min(ar,cr)){
ans+=QA[i]*QB[i]*QC[i]*(br-m-1)+SumABC[r];
if(ar<=cr)ans+=(SumB[ar-1]-SumB[br-1])*QA[i]*QC[i]+(SumAB[cr-1]-SumAB[ar-1])*QC[i]-SumABC[cr-1];
else ans+=(SumB[cr-1]-SumB[br-1])*QA[i]*QC[i]+(SumBC[ar-1]-SumBC[cr-1])*QA[i]-SumABC[ar-1];
}
else {
ans+=QA[i]*QB[i]*QC[i]*(cr-m-1)+SumABC[r];
if(ar<=br)ans+=(SumC[ar-1]-SumC[cr-1])*QA[i]*QB[i]+(SumAC[br-1]-SumAC[ar-1])*QB[i]-SumABC[br-1];
else ans+=(SumC[br-1]-SumC[cr-1])*QA[i]*QB[i]+(SumBC[ar-1]-SumBC[br-1])*QA[i]-SumABC[ar-1];
}
}
}
I void Solve3(int l,int r,U &ans){
if(l==r) return (void)(ans+=A[l]*B[l]*C[l]);re int m=l+r>>1,i;Solve3(l,m,ans);Solve3(m+1,r,ans);
QA[m+1]=A[m+1];QB[m+1]=B[m+1];QC[m+1]=C[m+1];for(i=m+2;i<=r;i++)QA[i]=max(QA[i-1],A[i]),QB[i]=min(QB[i-1],B[i]),QC[i]=min(QC[i-1],C[i]);
QA[m]=A[m];QB[m]=B[m];QC[m]=C[m];for(i=m-1;i>=l;i--)QA[i]=max(QA[i+1],A[i]),QB[i]=min(QB[i+1],B[i]),QC[i]=min(QC[i+1],C[i]);
SumA[m]=SumB[m]=SumC[m]=SumAB[m]=SumAC[m]=SumBC[m]=SumABC[m]=0;
for(i=m+1;i<=r;i++) SumA[i]=SumA[i-1]+QA[i],SumB[i]=SumB[i-1]+QB[i],SumC[i]=SumC[i-1]+QC[i],SumAB[i]=SumAB[i-1]+QA[i]*QB[i],SumAC[i]=SumAC[i-1]+QA[i]*QC[i],SumBC[i]=SumBC[i-1]+QB[i]*QC[i],SumABC[i]=SumABC[i-1]+QA[i]*QB[i]*QC[i];
ar=br=cr=m+1;for(i=m;i>=l;i--){
while(ar<=r&&QA[ar]<=QA[i]) ar++;while(br<=r&&QB[br]>=QB[i]) br++;while(cr<=r&&QC[cr]>=QC[i]) cr++;
if(ar<=min(br,cr)){
ans+=QA[i]*QB[i]*QC[i]*(ar-m-1)+SumABC[r];
if(br<=cr)ans+=(SumA[br-1]-SumA[ar-1])*QB[i]*QC[i]+(SumAB[cr-1]-SumAB[br-1])*QC[i]-SumABC[cr-1];
else ans+=(SumA[cr-1]-SumA[ar-1])*QB[i]*QC[i]+(SumAC[br-1]-SumAC[cr-1])*QB[i]-SumABC[br-1];
}
else if(br<=min(ar,cr)){
ans+=QA[i]*QB[i]*QC[i]*(br-m-1)+SumABC[r];
if(ar<=cr)ans+=(SumB[ar-1]-SumB[br-1])*QA[i]*QC[i]+(SumAB[cr-1]-SumAB[ar-1])*QC[i]-SumABC[cr-1];
else ans+=(SumB[cr-1]-SumB[br-1])*QA[i]*QC[i]+(SumBC[ar-1]-SumBC[cr-1])*QA[i]-SumABC[ar-1];
}
else {
ans+=QA[i]*QB[i]*QC[i]*(cr-m-1)+SumABC[r];
if(ar<=br)ans+=(SumC[ar-1]-SumC[cr-1])*QA[i]*QB[i]+(SumAC[br-1]-SumAC[ar-1])*QB[i]-SumABC[br-1];
else ans+=(SumC[br-1]-SumC[cr-1])*QA[i]*QB[i]+(SumBC[ar-1]-SumBC[br-1])*QA[i]-SumABC[ar-1];
}
}
}
I void Solve4(int l,int r,U &ans){
if(l==r) return (void)(ans+=A[l]*B[l]*C[l]);re int m=l+r>>1,i;Solve4(l,m,ans);Solve4(m+1,r,ans);
QA[m+1]=A[m+1];QB[m+1]=B[m+1];QC[m+1]=C[m+1];for(i=m+2;i<=r;i++)QA[i]=min(QA[i-1],A[i]),QB[i]=min(QB[i-1],B[i]),QC[i]=min(QC[i-1],C[i]);
QA[m]=A[m];QB[m]=B[m];QC[m]=C[m];for(i=m-1;i>=l;i--)QA[i]=min(QA[i+1],A[i]),QB[i]=min(QB[i+1],B[i]),QC[i]=min(QC[i+1],C[i]);
SumA[m]=SumB[m]=SumC[m]=SumAB[m]=SumAC[m]=SumBC[m]=SumABC[m]=0;
for(i=m+1;i<=r;i++) SumA[i]=SumA[i-1]+QA[i],SumB[i]=SumB[i-1]+QB[i],SumC[i]=SumC[i-1]+QC[i],SumAB[i]=SumAB[i-1]+QA[i]*QB[i],SumAC[i]=SumAC[i-1]+QA[i]*QC[i],SumBC[i]=SumBC[i-1]+QB[i]*QC[i],SumABC[i]=SumABC[i-1]+QA[i]*QB[i]*QC[i];
ar=br=cr=m+1;for(i=m;i>=l;i--){
while(ar<=r&&QA[ar]>=QA[i]) ar++;while(br<=r&&QB[br]>=QB[i]) br++;while(cr<=r&&QC[cr]>=QC[i]) cr++;
if(ar<=min(br,cr)){
ans+=QA[i]*QB[i]*QC[i]*(ar-m-1)+SumABC[r];
if(br<=cr)ans+=(SumA[br-1]-SumA[ar-1])*QB[i]*QC[i]+(SumAB[cr-1]-SumAB[br-1])*QC[i]-SumABC[cr-1];
else ans+=(SumA[cr-1]-SumA[ar-1])*QB[i]*QC[i]+(SumAC[br-1]-SumAC[cr-1])*QB[i]-SumABC[br-1];
}
else if(br<=min(ar,cr)){
ans+=QA[i]*QB[i]*QC[i]*(br-m-1)+SumABC[r];
if(ar<=cr)ans+=(SumB[ar-1]-SumB[br-1])*QA[i]*QC[i]+(SumAB[cr-1]-SumAB[ar-1])*QC[i]-SumABC[cr-1];
else ans+=(SumB[cr-1]-SumB[br-1])*QA[i]*QC[i]+(SumBC[ar-1]-SumBC[cr-1])*QA[i]-SumABC[ar-1];
}
else {
ans+=QA[i]*QB[i]*QC[i]*(cr-m-1)+SumABC[r];
if(ar<=br)ans+=(SumC[ar-1]-SumC[cr-1])*QA[i]*QB[i]+(SumAC[br-1]-SumAC[ar-1])*QB[i]-SumABC[br-1];
else ans+=(SumC[br-1]-SumC[cr-1])*QA[i]*QB[i]+(SumBC[ar-1]-SumBC[br-1])*QA[i]-SumABC[ar-1];
}
}
}
int main(){
freopen("d.in","r",stdin);freopen("d.out","w",stdout);
re int i;scanf("%d",&n);for(i=1;i<=n;i++) scanf("%u",&A[i]);for(i=1;i<=n;i++) scanf("%u",&B[i]);for(i=1;i<=n;i++) scanf("%u",&C[i]);
Solve1(1,n,ans1);Solve2(1,n,ans2);for(i=1;i<=n;i++) swap(A[i],B[i]);Solve2(1,n,ans2);for(i=1;i<=n;i++) swap(A[i],C[i]);Solve2(1,n,ans2);
Solve3(1,n,ans3);for(i=1;i<=n;i++) swap(A[i],B[i]);Solve3(1,n,ans3);for(i=1;i<=n;i++) swap(A[i],C[i]);Solve3(1,n,ans3);Solve4(1,n,ans4);printf("%u\n",ans1-ans2+ans3-ans4);
}