题解 CF1051G【Distinctification】
题意
给你两个长为 $n$ 的序列 $a$ 和 $b$,你可以进行两种操作若干次:
- 若有 $i\ne j$ 且 $a_i=a_j$,则可以令 $a_i\gets a_i+1$,代价为 $b_i$。
- 若有 $a_i=a_j+1$,则可以令 $a_i\gets a_i-1$,代价为 $-b_i$。
对于 $\forall i\in[1,n]$,求出最小的代价使得 $a_{1\dots i}$ 互不相同。
$1\le n,a_i\le 2\times 10^5$,$b$ 为一个 $[1,n]$ 的排列。
思路
最终的代价只与 $a_i$ 最终的值有关。
在一个值域连续段中,$a_i$ 的值无论如何操作都无法小于最小值,所以只是将 $a_i$ 或 $b_i$ 重新排序使得答案最小的问题。
可以发现,若 $a_i=a_j+1$,则可以交换 $a_i$,$a_j$,并花费 $b_j-b_i$ 的代价。所以如果 $a_i$ 在一个值域上的连续段中,则可以将 $b_i$ 降序排序,使得代价最小。
我们需要维护每个值域连续段并支持合并,考虑线段树合并。
对每个值域连续段的左端点建立权值线段树,以 $b_i$ 为下标,考虑到可以视为将小于 $mid$ 的值整体右移,答案为 $sum_{rt}\times l+\displaystyle\sum sum_{ls}\times siz_{rs}$。
用并查集找到连续段左端点并记录相应右端点。
数组记得开两倍。
时间复杂度 $O(n\log n)$。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
namespace IO{//by cyffff
}
const int N=4e5+10;
int n,f[N],br[N];
ll ans;
inline int find(int x){
return x==f[x]?x:f[x]=find(f[x]);
}
int rt[N];
struct Segument_Tree{
int son[2][N*60],cnt;
int siz[N*60];
ll sum[N*60];
#define ls (son[0][rt])
#define rs (son[1][rt])
inline void pushup(int rt){
sum[rt]=sum[ls]+sum[rs];
siz[rt]=siz[ls]+siz[rs];
}
inline void insert(int &rt,int l,int r,int p){
if(!rt)
rt=++cnt;
if(l==r){
sum[rt]=p,siz[rt]=1;
return ;
}
int mid=l+r>>1;
if(p<=mid) insert(ls,l,mid,p);
else insert(rs,mid+1,r,p);
pushup(rt);
}
inline int merge(int a,int b,int l,int r){
if(!a||!b) return a+b;
int rt=++cnt;
if(l==r) return rt;
ans-=sum[son[0][a]]*siz[son[1][a]]+
sum[son[0][b]]*siz[son[1][b]];
int mid=l+r>>1;
ls=merge(son[0][a],son[0][b],l,mid);
rs=merge(son[1][a],son[1][b],mid+1,r);
ans+=sum[ls]*siz[rs];
pushup(rt);
return rt;
}
}t;
inline void solve(int u,int v){
u=find(u),v=find(v),f[v]=u;
ans-=t.sum[rt[u]]*u+t.sum[rt[v]]*v;
rt[u]=t.merge(rt[u],rt[v],1,n);
ans+=t.sum[rt[u]]*u;
br[u]=br[v];
}
int main(){
n=read();
for(int i=1;i<=N-10;i++)
f[i]=br[i]=i;
for(int i=1;i<=n;i++){
int p=read(),v=read();
int xp=rt[p]?br[find(p)]+1:p;
ans+=1ll*(xp-p)*v;
t.insert(rt[xp],1,n,v);
if(rt[xp-1]) solve(xp-1,xp);
if(rt[xp+1]) solve(xp,xp+1);
write(ans),putc('\n');
}
flush();
}
再见 qwq~

浙公网安备 33010602011771号