CF2024C-Concatenation--of-Arrays-题解
CF2024C
题意简述
给定 $n$ 个二维数组,每个 数组的长度为 $2$,将这 $n$ 个数组连接起来,要使得数组中的逆序对数量尽可能的少。
题意分析
题目要求排列数组使得逆序对尽可能少,对于其中一个数组,其可能贡献的逆序对数量为比 $a_{i,1}$ 小的个数 $x$,加上比 $a_{i,2}$ 小的个数 $y$,设 $cnt_i$ 为 $x+y$,之后只需要对数组 $cnt$ 排序输出结果即可。
注意,只要 $a_{i,1}$ 和 $a_{i,2}$ 不相同,得出的结果应该减去 $1$,这是因为必然会有一个数比另一个数小,所以要排除掉。
关于求解比当前数小的个数,我们可以使用二分查找函数lower_bound来求解。
Code
#pragma GCC optimize(1, 2, 3, "Ofast", "inline")
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define int ll
#define ONLINE_JUDGE
#define MULTI_CASES
#define endl '\n'
const int MaxN = 2e5+100;
const int INF = 1e9;
const int mod=212370440130137957ll;
int T=1, N, M;
// int a[MaxN];
struct node{
int x,y;
int id;
}a[MaxN];
bool cmp1(node a,node b){
return min(a.x,a.y)<min(b.x,b.y);
}
bool cmp2(node a,node b){
return max(a.x,a.y)>max(b.x,b.y);
}
bool cmp(node a,node b){
return a.id<b.id;
}
int cnt[MaxN];
inline void Solve()
{
cin>>N;
for(int i=1;i<=N;i++){
cin>>a[i].x>>a[i].y;
a[i].id=i;
}
vector<int>b;
for(int i=1;i<=N;i++){
b.push_back(a[i].x);
b.push_back(a[i].y);
}
sort(b.begin(),b.end());
for(int i=1;i<=N;i++){
if(a[i].x<a[i].y){
int x=lower_bound(b.begin(),b.end(),a[i].x)-b.begin();
int y=lower_bound(b.begin(),b.end(),a[i].y)-b.begin()-1;
cnt[i]=x+y;
}
else{
if(a[i].x>a[i].y){
int x=lower_bound(b.begin(),b.end(),a[i].x)-b.begin()-1;
int y=lower_bound(b.begin(),b.end(),a[i].y)-b.begin();
cnt[i]=x+y;
}
else{
int x=lower_bound(b.begin(),b.end(),a[i].x)-b.begin();
int y=lower_bound(b.begin(),b.end(),a[i].y)-b.begin();
cnt[i]=x+y;
}
}
}
for(int i=1;i<=N;i++){
a[i].id=cnt[i];
}
sort(a+1,a+N+1,cmp);
for(int i=1;i<=N;i++){
cout<<a[i].x<<" "<<a[i].y<<" ";
}
cout<<endl;
}
signed main()
{
#ifndef ONLINE_JUDGE
freopen(".in", "r", stdin);
freopen(".out", "w", stdout);
#endif
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
#ifdef MULTI_CASES
cin >> T;
while (T--)
#endif
Solve();
//fclose(stdin);
//fclose(stdout);
return 0;
}
本文采用 CC BY-NC 4.0 许可协议,转载请注明出处并保持非商业用途。