开始做题目有一个很重要的条件没注意,做的我相当的苦逼,看了别人的思路,都说很简单。
我却完全不懂,当时想死的心情都有了。不过在队友的提醒下才恍然大悟,原来A数组的值是确定的。
然后去想就感觉理应如此了,先前没看懂的时候写了个暴力代码水过,看清题目后用线段树写速度真不是盖的。
我却完全不懂,当时想死的心情都有了。不过在队友的提醒下才恍然大悟,原来A数组的值是确定的。
然后去想就感觉理应如此了,先前没看懂的时候写了个暴力代码水过,看清题目后用线段树写速度真不是盖的。
暴力代码:
#include<stdio.h>
#include<iostream>
#define Min(a,b) a<b?a:b
using namespace std;
const int size=5000;
__int64 ans,minx;
int a[size+10],up[size+10],down[size+10];
int main()
{
int i,j,n,sum,minx;
while (~scanf("%d",&n))
{
memset(down,0,sizeof(down));
memset(up,0,sizeof(up));
for (i=sum=0;i<n;i++)
{
scanf("%d",a+i);
for (j=0;j<i;j++)
{
if (a[j]<a[i]) up[j]++,down[i]++;
if (a[j]>a[i]) sum++,up[i]++,down[j]++;
}
}
for (minx=sum,i=0;i<n;i++)
{
sum=sum-down[i]+up[i];
minx=Min(minx,sum);
}
printf("%d\n",minx);
}
return 0;
}
线段树代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
#define Min(a,b) a<b?a:b
using namespace std;
const int size=5000;
int sum[size<<2],arr[size+10];
void push(int rt)
{
sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void update(int l,int r,int k,int rt)
{
if (l==r)
{
sum[rt]++;
return ;
}
int mid=(l+r)>>1;
if (k<=mid) update(l,mid,k,rt<<1);
else update(mid+1,r,k,rt<<1|1);
push(rt);
}
int query(int l,int r,int a,int b,int rt)
{
if (a<=l&&b>=r) return sum[rt];
int mid=(l+r)>>1,r1=0,r2=0;
if (a<=mid) r1=query(l,mid,a,b,rt<<1);
if (b>mid) r2=query(mid+1,r,a,b,rt<<1|1);
return r1+r2;
}
int main()
{
int i,k,n,sumx,minx;
while (~scanf("%d",&n))
{
memset(sum,0,sizeof(sum));
for (i=sumx=0;i<n;i++)
{
scanf("%d",arr+i);
sumx+=query(0,n-1,arr[i]+1,n-1,1);
update(0,n-1,arr[i],1);
}
for (minx=sumx,i=0;i<n-1;i++)
{
// printf("minx=%d\n",minx);
sumx+=n-1-arr[i]-arr[i];
minx=Min(sumx,minx);
}
printf("%d\n",minx);
}
return 0;
}