专栏文章
题解:CF1725L Lemper Cooking Competition
CF1725L题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @miqjc4tt
- 此快照首次捕获于
- 2025/12/04 05:44 3 个月前
- 此快照最后确认于
- 2025/12/04 05:44 3 个月前
题意
定义一次操作为依次执行以下内容:
- 选定一个满足 的整数 。
- 令 。
- 令 。
- 令 。
现在进行若干次操作,求将 的每个元素都变为非负的操作次数。无解输出
-1。解法
我们观察题面的三步操作,容易注意到执行完操作后整个数组的前缀和不变。
我们令 为 的前缀和数组,那么我们可以把操作转化为交换 和 。让原数组非负就是让 递增且没有负数。
于是本题就转化为了求逆序对数。无解的两种情况:
我们令 为 的前缀和数组,那么我们可以把操作转化为交换 和 。让原数组非负就是让 递增且没有负数。
于是本题就转化为了求逆序对数。无解的两种情况:
- 中存在负数。
- 不是最大值。因为 不能参与交换。
CODE:
CPP//luogu paste jo5j6ogx
cst int N=1e5;
int n,b[N+10],m;
ll s[N+10],a[N+10],ans;
umap<ll,int>mp;
il void add(int x,int y){
while(x<=m){
b[x]+=y;
x+=lowbit(x);
}
}
il int sum(int x){
int s=0;
while(x){
s+=b[x];
x-=lowbit(x);
}
ret s;
}
il int sum(int l,int r){ret sum(r)-sum(l-1);}
int main(void){
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
n=read<int>();
for(int i=1;i<=n;i++){
a[i]=s[i]=s[i-1]+read<ll>();
if(s[i]<0){
write(-1);ret 0;
}
}
for(int i=1;i<n;i++){
if(s[i]>s[n]){
write(-1);ret 0;
}
}
sort(a+1,a+n);
m=unique(a+1,a+n)-a-1;
for(int i=1;i<=m;i++) mp[a[i]]=i;
for(int i=1;i<n;i++){
s[i]=mp[s[i]];
ans+=sum(s[i]+1,m);
add(s[i],1);
}
write(ans);
ret 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...