- 基本介绍
- 模板题目
- 代码实现
基本介绍
逆序对就是序列的实际排序和期望排序的比较 例如
1 2 10 8 6 4 是一个序列
那么按大小给他们编上号就是 1 2 6 5 4 3
但我们期望从小到大的排序是 1 2 3 4 5 6
所以我们从前往后来看 1 2 6 都是按顺序来的 到了5 它比6小 所以 6 5 是一对逆序对 同理还有 6 4 | 5 4 | 6 3 | 5 3 | 4 3 一共6对
这就是逆序对
所以面对一个序列 我们很容易想出一个O(n^2)的作法
#include<iostream>
#include<cstdio>
#include<cctype>
using namespace std;
#define in = read()
typedef long long ll;
const ll size = 40000 + 1000;
ll n;
ll a[size];
ll ans;
inline ll read(){
ll num = 0 , f = 1; char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') f = -1;
ch = getchar();
}
while(isdigit(ch)){
num = num*10 + ch - '0';
ch = getchar();
}
return num*f;
}
int main(){
n in;
for(int i=1;i<=n;i++) a[i] in;
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++)
if(a[j] < a[i])
ans ++;
printf("%d",ans);
}
//COYG
但是数据大的话会很慢
于是改用树状数组 O(n*logn)
#include<iostream>
#include<cstdio>
#include<cctype>
using namespace std;
#define in = read()
typedef long long ll;
const ll size = 4000000 + 1000;
#define lowbit(x) (x & -x)
ll n,m;
ll c[size];
ll total;
inline ll read(){
ll num = 0 , f = 1; char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') f = -1;
ch = getchar();
}
while(isdigit(ch)){
num = num*10 + ch - '0';
ch = getchar();
}
return num*f;
}
inline void add(ll x,ll y){
while(x<=n){
c[x] += y;
x += lowbit(x);
}
}
inline ll sum(ll x){
ll ans = 0;
while(x > 0){
ans += c[x];
x -= lowbit(x);
}
return ans;
}
int main(){
n in;
for(int i=1;i<=n;i++){
ll x; x in;
add(x,1);
total += i - sum(x);
}
printf("%d",total);
}
//COYG
这样可能会好一些 但是还是不能完成目标 空间问题暴露出来
于是离散化
代码见下
模板题目
把题复制来好像超字数限制了
题目
代码实现
#include<iostream>
#include<cstdio>
#include<cctype>
#include<algorithm>
using namespace std;
#define in = read()
typedef long long ll;
const ll size = 40000 + 1000;
#define lowbit(x) (x & -x)
ll n,m;
ll a[size];
ll total;
ll c[size],id[size];
inline ll read(){
ll num = 0 , f = 1; char ch = getchar();
while(!isdigit(ch)){
if(ch == '-') f = -1;
ch = getchar();
}
while(isdigit(ch)){
num = num*10 + ch - '0';
ch = getchar();
}
return num*f;
}
bool cmp(ll x,ll y){
return a[x] < a[y];
}
inline void add(ll x,ll y){
while(x<=n){
c[x] += y;
x += lowbit(x);
}
}
inline ll sum(ll x){
ll ans = 0;
while(x > 0){
ans += c[x];
x -= lowbit(x);
}
return ans;
}
int main(){
n in;
for(int i=1;i<=n;i++){
a[i] in;
id[i] = i;
}
sort(id+1,id+n+1,cmp);
for(int i=1;i<=n;i++)
a[id[i]] = i;
for(int i=1;i<=n;i++){
add(a[i],1);
total += i - sum(a[i]);
}
printf("%d",total);
}
//COYG