P13509 [OOI 2024] Almost Certainly 题解
Coffee_zzz · · 题解
考虑维护一棵值域线段树
由于「几乎等价」等价于「各删除一个数后完全相等」,设我们删除的是
可以离散化一下,时间复杂度
#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;
}