树状数组和线段树都可做
树状数组代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 5000 + 50;
int n;
int a[maxn],c[maxn];
int lowbit(int x) {return x&-x;}
void add(int i, int x)
{
while(i <= n){
c[i] += x;
i += lowbit(i);
}
}
int query(int i)
{
int ans = 0;
while(i){
ans += c[i];
i -= lowbit(i);
}
return ans;
}
int main()
{
//freopen("DATA.c", "r", stdin);
while(~scanf("%d", &n)){
int ans = 0;
memset(c,0,sizeof(c));
for(int i = 1; i <= n; i ++){
scanf("%d", &a[i]); ++ a[i];
ans += query(n) - query(a[i]);
add(a[i],1);
}
int ret = ans;
for(int i = 1; i <= n; i ++){
ans += (n-a[i]) - (a[i]-1);
ret = min(ret, ans);
}
printf("%d\n", ret);
}
return 0;
}
线段树代码(PS:第一次手写线段树):
#include<bits/stdc++.h>
using namespace std;
const int maxn = 5000 + 50;
int n,a[maxn];
struct Node
{
int l;
int r;
int sum;
int add;
}segTree[maxn<<2];
void PushDown(int i)
{
if(segTree[i].add){
int m = (segTree[i].r - segTree[i].l + 1) >> 1;
segTree[i<<1].add += segTree[i].add;
segTree[i<<1|1].add += segTree[i].add;
segTree[i<<1].sum += segTree[i].add * m;
segTree[i<<1|1].sum += segTree[i].add * (segTree[i].r - segTree[i].l + 1 - m);
segTree[i].add = 0;
}
}
void PushUp(int i)
{
segTree[i].sum = segTree[i<<1].sum + segTree[i<<1|1].sum;
}
void Build(int i, int l, int r)
{
segTree[i].l = l;
segTree[i].r = r;
segTree[i].sum = 0;
segTree[i].add = 0;
if(l == r) return ;
int mid = l + r >> 1;
Build(i<<1,l,mid);
Build(i<<1|1,mid+1,r);
}
void Update(int i, int l, int r, int v)
{
if(l <= segTree[i].l && segTree[i].r <= r){
segTree[i].sum += v * (segTree[i].r - segTree[i].l + 1);
segTree[i].add += v;
return ;
}
PushDown(i);
int mid = segTree[i].l + segTree[i].r >> 1;
if(r <= mid){
Update(i<<1,l,r,v);
}
else if(l > mid){
Update(i<<1|1,l,r,v);
}
else{
Update(i<<1,l,mid,v);
Update(i<<1|1,mid+1,r,v);
}
PushUp(i);
}
int Query(int i, int l, int r)
{
if(l <= segTree[i].l && segTree[i].r <= r){
return segTree[i].sum;
}
PushDown(i);
int mid = segTree[i].l + segTree[i].r >> 1;
int ans = 0;
if(r <= mid){
ans += Query(i<<1,l,r);
}
else if(l > mid){
ans += Query(i<<1|1,l,r);
}
else{
ans += Query(i<<1,l,mid);
ans += Query(i<<1|1,mid+1,r);
}
return ans;
}
int main()
{
//freopen("DATA.c", "r", stdin);
while(~scanf("%d", &n)){
int ans = 0;
Build(1,1,n);
for(int i = 1; i <= n; i ++){
scanf("%d", &a[i]); ++a[i];
ans += Query(1,1,n) - Query(1,1,a[i]);
Update(1,a[i],a[i],1);
}
int ret = ans;
for(int i = 1; i <= n; i ++){
ans += (n-a[i])-(a[i]-1);
ret = min(ret,ans);
}
printf("%d\n", ret);
}
return 0;
}