Atcoder agc028C

63 篇文章 0 订阅
27 篇文章 1 订阅

考虑将所有的 A A A B B B从小到大排序。
若前 n n n小中全部都是 A A A或全部都是 B B B容易构造达到下界。否则若同时存在某个 A i A_i Ai B i B_i Bi也可以构造达到下界(同时存在 A i A_i Ai B i B_i Bi i i i的个数等于同时不存在 A i A_i Ai B i B_i Bi i i i的个数,那么我们可以在环上交替放两种数,最后将剩余的只存在 A i A_i Ai或只存在 B i B_i Bi的数插在它们之间)。
如果既有 A A A也有 B B B,且每个 i i i恰好出现一次的话,我们枚举一个后面的替换即可,注意有可能换成全部是 A A A或全部是 B B B的。
时间复杂度 O ( N log ⁡ N ) \mathcal O(N\log N) O(NlogN)

#include <bits/stdc++.h>
#define FR first
#define SE second

using namespace std;

typedef long long ll;
typedef pair<int,int> pr;

pr a[200005],num[100005];
bool vis[100005];

int main() {
  int n;
  scanf("%d",&n);
  ll s1=0,s2=0;
  for(int i=1;i<=n;i++) {
  	int x,y;
  	scanf("%d%d",&x,&y);
  	a[2*i-1]=pr(x,i);
  	a[2*i]=pr(y,i);
  	s1+=x;s2+=y;
  	num[i]=pr(x,y);
  }
  sort(a+1,a+2*n+1);
  ll s=0;
  bool ok=0;
  for(int i=1;i<=n;i++) {
  	s+=a[i].FR;
    if (!vis[a[i].SE]) vis[a[i].SE]=1;
    else ok=1;
  }
  if (ok) {
  	printf("%lld\n",s);
  	return 0;
  }
  ll ans=min(s1,s2);
  for(int i=1;i<=n;i++) {
  	int x=a[i].SE;
  	ans=min(ans,s-a[i].FR+num[x].FR+num[x].SE-((i==n)?a[n-1].FR:a[n].FR));
  }
  printf("%lld\n",ans);
  return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值