Codeforces Round #835 (Div. 4)

Dashboard - Codeforces Round #835 (Div. 4) - Codeforces

E. Binary Inversions

题意:给定一个长度为n的0 1串 ,你可以执行以下操作最多一次(可能为0):将 0 翻转 成 1,或将 1 翻转成 0 。求最大逆序对数。

思路:首先求出原串的逆序对的对数。然后可以枚举每一位翻转的贡献,取贡献的最大值,若最大的贡献<0 ,则无需进行该操作输出原串的逆序对数,否则就是原逆序对数+最大贡献。对于每一位的贡献,用前缀和维护即可,0变1的贡献为:后面的0个数-前面1的个数,1变0的贡献为:前面1的个数-后面0的个数。

#include<bits/stdc++.h>
#define int long long
#define PII pair<int,int> 
#define ios ios::sync_with_wtdio(false);cin.tie(0);cin.tie(0)

using namespace std;

const int N=2e5+10;
int a[N];
int n;
int psum[N];
int tmp[N];
int b[N];

long long merge_sort(int q[],int l,int r) 
{
	if(l>=r)  return 0;
	
	int mid=(l+r)/2;
	int k=0;
	long long ans=merge_sort(q,l,mid)+merge_sort(q,mid+1,r);
	int i=l,j=mid+1;
	while(i<=mid && j<=r)
	{
		if(q[i]<=q[j])  tmp[k++]=q[i++];
		else {
			tmp[k++]=q[j++];
			ans += mid-i+1;
		}
	}
	while(i<=mid) tmp[k++]=q[i++];
	while(j<=r)   tmp[k++]=q[j++];
	
	for(int i=l,j=0;i<=r;j++,i++)
	q[i]=tmp[j];
	
	return ans;
}

void solve(){
	cin >> n;
	for(int i=1;i<=n;i++){
		cin >> a[i];
		b[i]=a[i];
		psum[i]=psum[i-1]+a[i];
	}
	int mx=-1;
	int num;

	num=merge_sort(b,1,n);
	for(int i=1;i<=n;i++){
		int q1=psum[i-1];
		int e1=n-i-(psum[n]-psum[i]);
		if(a[i]==1)mx=max(q1-e1,mx);
		else mx=max(e1-q1,mx);
	}
	if(mx<0) mx=0;
	cout << mx+num << endl;
}

signed main(){
	int t=1;
	cin >> t;
	while(t--){
		solve();
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值