专栏文章

P13509 [OOI 2024] Almost Certainly 题解

P13509题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@minp4vm3
此快照首次捕获于
2025/12/02 06:03
3 个月前
此快照最后确认于
2025/12/02 06:03
3 个月前
查看原文
考虑维护一棵值域线段树 TT。对于每一个 ii,将 TT[bi+1,ai][b_i+1,a_i] 的位置的值加 11,于是 aa 可以变成 bb 当且仅当 TT 上每一个位置都大于等于 00,此时需要的操作次数为 i=1maii=1mbi\sum\limits_{i=1}^m a_i-\sum\limits_{i=1}^m b_i
由于「几乎等价」等价于「各删除一个数后完全相等」,设我们删除的是 axa_xbyb_y,那么我们希望删除的 bxayb_x-a_y 尽可能大,这样才能使操作次数尽可能小。但是我们要保证删除后 TT 上每一个位置都大于等于 00,所以需要满足 TT[ay,bx][a_y,b_x] 的每一个位置都大于等于 11,于是在 TT 上计算最长的大于等于 11 的区间的长度即可。
可以离散化一下,时间复杂度 O(nlogn)\mathcal O(n \log n)
C
#define int long long
const int N=2e5+5,inf=2e9;
int n,m,ans,a[N],b[N],t[N<<1],val[N<<3],lef[N<<3],rig[N<<3],mid[N<<3],sum[N<<3];
bool tag[N<<3];
void upd(int g){
	sum[g]=sum[g<<1]+sum[g<<1|1];
	lef[g]=max(lef[g<<1],val[g<<1]+lef[g<<1|1]);
	lef[g]=max(lef[g],val[g<<1]);
	rig[g]=max(rig[g<<1|1],rig[g<<1]+val[g<<1|1]);
	rig[g]=max(rig[g],val[g<<1|1]);
	mid[g]=max(mid[g<<1],mid[g<<1|1]);
	mid[g]=max(mid[g],rig[g<<1]+lef[g<<1|1]);
	mid[g]=max(mid[g],max(lef[g<<1|1],rig[g<<1]));
	val[g]=val[g<<1]+val[g<<1|1];
}
void down(int g){
	if(tag[g]){
		tag[g<<1]=tag[g<<1|1]=1;
		tag[g]=0;
		mid[g<<1]=lef[g<<1]=rig[g<<1]=val[g<<1]=sum[g<<1];
		mid[g<<1|1]=lef[g<<1|1]=rig[g<<1|1]=val[g<<1|1]=sum[g<<1|1];
	}
}
void build(int g,int l,int r){
	tag[g]=0;
	if(l==r){
		sum[g]=t[r]-t[r-1];
		mid[g]=0;
		lef[g]=rig[g]=val[g]=-inf;
		return;
	}
	int m=(l+r)>>1;
	build(g<<1,l,m);
	build(g<<1|1,m+1,r);
	upd(g);
}
void modify(int g,int l,int r,int x,int y){
	if(x<=l&&r<=y) return mid[g]=lef[g]=rig[g]=val[g]=sum[g],tag[g]=1,void();
	if(r<x||y<l) return;
	int m=(l+r)>>1;
	down(g);
	modify(g<<1,l,m,x,y);
	modify(g<<1|1,m+1,r,x,y);
	upd(g);
}
void solve(){
	cin>>n,ans=0;
	for(int i=1;i<=n;i++) cin>>a[i],t[i]=a[i];
	for(int i=1;i<=n;i++) cin>>b[i],t[i+n]=b[i];
	sort(t+1,t+n+n+1);
	m=unique(t+1,t+n+n+1)-t-1;
	build(1,1,m);
	for(int i=1;i<=n;i++){
		ans+=a[i]-b[i];
		int x=lb(t+1,t+m+1,b[i])-t,y=lb(t+1,t+m+1,a[i])-t;
		modify(1,1,m,x+1,y);
		cout<<ans-max(mid[1],max(lef[1],max(rig[1],val[1])))<<' ';
	}
	cout<<endl;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...