求助卡空
查看原帖
求助卡空
520748
_Ch1F4N_楼主2023/10/20 16:49

如题,空间是 O(n)O(n) 的。

#include<bits/stdc++.h>
const int mod = 1e9;
using namespace std;
const int maxn = 5e5+14;
int ans,n;
int a[maxn];
int mx[maxn],mi[maxn];
struct Node{
	int mx,mi,len;
	Node(int MX=0,int MI=0,int LEN=0){
		mx=MX,mi=MI,len=LEN;
	}
};
vector<Node> vec[maxn]; 
int tr[maxn][2];//len mi*len mi
unordered_map<int,int> f;
int mp[maxn];
vector<int> S;
#define lowbit(x) (x&(-x))
inline void add(int u,int v,int type){
	v%=mod;
	while(u<maxn) tr[u][type]+=v,tr[u][type]%=mod,u+=lowbit(u);
}
inline int pre(int u,int type){
	int res=0;
	while(u>0) res+=tr[u][type],res%=mod,u-=lowbit(u);
	return res;
}
inline int ask(int l,int r,int type){
	return (pre(r,type)+mod-pre(l-1,type))%mod;
}
inline void solve(int l,int r){
	if(l==r){
		ans=(ans+1ll*mp[a[l]]*mp[a[l]])%mod;
		return ;
	}
	int mid=(l+r)>>1;
	solve(l,mid);
	solve(mid+1,r);
	mx[mid]=mi[mid]=a[mid];
	for(int i=mid-1;i>=l;i--) mx[i]=max(mx[i+1],a[i]),mi[i]=min(mi[i+1],a[i]);
	mx[mid+1]=mi[mid+1]=a[mid+1];
	for(int i=mid+2;i<=r;i++) mx[i]=max(mx[i-1],a[i]),mi[i]=min(mi[i-1],a[i]);
	//最大值在左边
	for(int i=mid;i>=l;i--){
		if(mx[mid+1]>mx[i]) continue;
		int lt=mid+1,rt=r+1;
		while(lt+1<rt){
			int MID=(lt+rt)>>1;
			if(mx[MID]<=mx[i]) lt=MID;
			else rt=MID;
		}
		vec[lt].push_back(Node(mp[mx[i]],mi[i],mid-i+1));
	}
	for(int i=mid+1;i<=r;i++){
		add(mi[i],1,0);
		add(mi[i],i-mid,1);
		//add(mi[i],1ll*mp[mi[i]]*(i-mid)%mod,2);
		//add(mi[i],mp[mi[i]],3);
		for(Node now:vec[i]){
			ans=(ans+((1ll*ask(now.mi,500005,1)*mp[now.mi]%mod)+(1ll*(1ll*mp[now.mi]*now.len%mod)*ask(now.mi,500005,0)%mod)%mod)*now.mx)%mod;
			//ans=(ans+1ll*((ask(1,now.mi-1,2)+1ll*(1ll*ask(1,now.mi-1,3)*now.len%mod))%mod)*now.mx)%mod;
		}
		//vec[i].clear();
	}
	for(int i=mid+1;i<=r;i++){
		add(mi[i],mod-1,0);
		add(mi[i],mod-(i-mid),1);
		//add(mi[i],mod-(1ll*mp[mi[i]]*(i-mid)%mod),2);
		//add(mi[i],mod-mp[mi[i]],3);
	}
	for(int i=mid+1;i<=r;i++){
		add(mi[i],1ll*mp[mi[i]]*(i-mid)%mod,0);
		add(mi[i],mp[mi[i]],1);
		for(Node now:vec[i]){
			//ans=(ans+((1ll*ask(now.mi,500005,1)*mp[now.mi]%mod)+(1ll*(1ll*mp[now.mi]*now.len%mod)*ask(now.mi,500005,0)%mod)%mod)*now.mx)%mod;
			ans=(ans+1ll*((ask(1,now.mi-1,0)+1ll*(1ll*ask(1,now.mi-1,1)*now.len%mod))%mod)*now.mx)%mod;
		}
		vec[i].clear();
	}
	for(int i=mid+1;i<=r;i++){
		//add(mi[i],mod-1,0);
		//add(mi[i],mod-(i-mid),1);
		add(mi[i],mod-(1ll*mp[mi[i]]*(i-mid)%mod),0);
		add(mi[i],mod-mp[mi[i]],1);
	}
	//最大值在右边
	for(int i=mid+1;i<=r;i++){
		int lt=l-1,rt=mid;
		if(mx[mid]>=mx[i]) continue;
		while(lt+1<rt){
			int MID=(lt+rt)>>1;
			if(mx[MID]<mx[i]) rt=MID;
			else lt=MID;
		}
		vec[rt].push_back(Node(mp[mx[i]],mi[i],i-mid));
	}
	for(int i=mid;i>=l;i--){
		add(mi[i],1,0);
		add(mi[i],mid-i+1,1);
		//add(mi[i],mp[mi[i]]*(mid-i+1)%mod,2);
		//add(mi[i],mp[mi[i]],3);
		for(Node now:vec[i]){
			ans=(ans+((1ll*ask(now.mi,500005,1)*mp[now.mi]%mod)+(1ll*(1ll*mp[now.mi]*now.len%mod)*ask(now.mi,500005,0)%mod)%mod)*now.mx)%mod;
			//ans=(ans+1ll*((ask(1,now.mi-1,2)+1ll*(1ll*ask(1,now.mi-1,3)*now.len%mod))%mod)*now.mx)%mod;
		}
		//vec[i].clear();
	}
	for(int i=mid;i>=l;i--){
		add(mi[i],mod-1,0);
		add(mi[i],mod-(mid-i+1),1);
		//add(mi[i],mod-(1ll*mp[mi[i]]*(mid-i+1)%mod),2);
		//add(mi[i],mod-mp[mi[i]],3);
	}
	for(int i=mid;i>=l;i--){
		//add(mi[i],1,0);
		//add(mi[i],mid-i+1,1);
		add(mi[i],mp[mi[i]]*(mid-i+1)%mod,0);
		add(mi[i],mp[mi[i]],1);
		for(Node now:vec[i]){
			//ans=(ans+((1ll*ask(now.mi,500005,1)*mp[now.mi]%mod)+(1ll*(1ll*mp[now.mi]*now.len%mod)*ask(now.mi,500005,0)%mod)%mod)*now.mx)%mod;
			ans=(ans+1ll*((ask(1,now.mi-1,0)+1ll*(1ll*ask(1,now.mi-1,1)*now.len%mod))%mod)*now.mx)%mod;
		}
		vec[i].clear();
	}
	for(int i=mid;i>=l;i--){
		//add(mi[i],mod-1,0);
		//add(mi[i],mod-(mid-i+1),1);
		add(mi[i],mod-(1ll*mp[mi[i]]*(mid-i+1)%mod),0);
		add(mi[i],mod-mp[mi[i]],1);
	}
}
int main(){
	//freopen("swamp.in","r",stdin);
	//freopen("swamp.out","w",stdout);
	ios::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i],S.push_back(a[i]);
	sort(S.begin(),S.end());
	for(int x:S) if(f[x]==0) f[x]=f.size()+1,mp[f[x]]=x;
	for(int i=1;i<=n;i++) a[i]=f[a[i]];
	solve(1,n);
	cout<<ans<<'\n';
	return 0;
}
2023/10/20 16:49
加载中...