LOJ #535 题解

问题转化为交换两个数,使排列的逆序对数最少。

设交换 aiaji<j,ai>aj。则减小的逆序对数为

1+k=i+1j1[ak<ai][ak>ai]+[ak>aj][ak<aj]=1+2k=i+1j1[aj<ak<ai]

显然最优者满足 ai=maxkiak,aj=minkjak。两者的可行集分别记为 A,B

对于每个点 (i,ai),求出 A 中第一关键字更小,第二关键字更大者;B 中第一关键字更大,第二关键字更小者,得出能覆盖这个点的所有矩形。

则形成 n 个矩形,求覆盖最多的地方,扫描线。

#include<bits/stdc++.h>
using namespace std;
constexpr int N=3e5+5;
int n,h[N],A[N],B[N],totA,totB,xL[N<<1],xR[N<<1],yL[N<<1],yR[N<<1],dat[N<<3],tag[N<<3],c[N];
struct Opt{int L,R,val;};vector<Opt>op[N];
inline void add(int p){
	for(;p<=n;p+=p&-p)c[p]++;
}
inline int get(int p){
	int ret=0;for(;p;p^=p&-p)ret+=c[p];
	return ret;
}
inline void pushdown(int p){
	dat[p<<1]+=tag[p];dat[p<<1|1]+=tag[p];
	tag[p<<1]+=tag[p];tag[p<<1|1]+=tag[p];
	tag[p]=0;
}
inline void upd(int p,int l,int r,int L,int R,int x){
	if(L<=l&&r<=R)return dat[p]+=x,tag[p]+=x,void();
	pushdown(p);int mid=(l+r)>>1;
	if(L<=mid)upd(p<<1,l,mid,L,R,x);
	if(R>mid)upd(p<<1|1,mid+1,r,L,R,x);
	dat[p]=max(dat[p<<1],dat[p<<1|1]);
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);cin>>n;long long S=0;
	for(int i=1;i<=n;i++){
		cin>>h[i];S+=i-get(h[i])-1;add(h[i]);
	}
	for(int i=1,mx=0;i<=n;i++)if(h[i]>mx)A[++totA]=i,mx=h[i];
	for(int i=n,mi=n+1;i;i--)if(h[i]<mi)B[++totB]=i,mi=h[i];
	reverse(B+1,B+totB+1);
	for(int i=1;i<=n;i++)xR[i]=lower_bound(A+1,A+totA+1,i)-A-1;
	for(int i=1;i<=n;i++)A[i]=h[A[i]];
	for(int i=1;i<=n;i++)xL[i]=upper_bound(A+1,A+totA+1,h[i])-A;
	for(int i=1;i<=n;i++)yL[i]=upper_bound(B+1,B+totB+1,i)-B;
	for(int i=1;i<=n;i++)B[i]=h[B[i]];
	for(int i=1;i<=n;i++)yR[i]=lower_bound(B+1,B+totB+1,h[i])-B-1;
	for(int i=1;i<=n;i++)if(xL[i]<=xR[i]&&yL[i]<=yR[i]){
		//printf("%d: x[%d,%d]; y[%d,%d]\n",i,xL[i],xR[i],yL[i],yR[i]);
		op[xL[i]].push_back({yL[i],yR[i],1});
		op[xR[i]+1].push_back({yL[i],yR[i],-1});
	}
	int ans=0;
	for(int i=1;i<=totA;i++){
		for(auto k:op[i])upd(1,1,totB,k.L,k.R,k.val);
		ans=max(ans,dat[1]);
	}
	cout<<S-ans*2<<endl;
	return 0;
}
posted @   hihihi198  阅读(88)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
主题色彩