题目简短易懂,求给定序列中的逆序对。
序列最长有65537个数,o(n^2)的暴力会tle。
可用归并排序来达到o(nlogn)。
刚好以前听老师讲过逆序对,看完题目直接敲代码。
手残敲了2、30min。。大概是。。
一提交wa。。。各种纠结,想不出哪能wa
代码如下
#include <iostream>
#include <cstdio>
using namespace std;
#define MAX 65537+5
int a[MAX],t[MAX],cnt;
void count(int a[],int l,int r)
{
if(l>=r)
return;
int m;
m=(l+r)/2;
count(a,l,m);
count(a,m+1,r);
int p,q,i;
p=l;
q=m+1;
i=0;
while(p<=m&&q<=r)
{
if(a[p]<=a[q])
t[i++]=a[p++];
else
{
t[i++]=a[q++];
cnt+=m-p+1;
}
}
while(p<=m)
t[i++]=a[p++];
while(q<=r)
t[i++]=a[q++];
int j,k;
for(j=l,k=0;j<=r&&k<i;j++,k++)
a[j]=t[k];
}
void solve(int n)
{
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
cnt=0;
count(a,0,n-1);
//for(int i=0;i<n;i++)printf("%d ",a[i]);printf("\n");
printf("%d\n",cnt);
}
int main()
{
// freopen("in.txt","r",stdin);
int n;
while(scanf("%d",&n)>0)
solve(n);
return 0;
}
没错,就是坑爹的数据范围,65537个数的序列,在极端情况下有大概65537*65537/2个逆序对,而int的数据范围是21多亿。。
改龙龙于是ac
手残+罚时=被虐成渣
--------------------------
为了避免以后再犯类似的2b错误,整形尽量用龙龙,
为了不麻烦,输入输出用cin,cout
为了效率加一句:ios_base::sync_with_stdio(false);
经个人简单测试
重定向文件输入100w个整形数据的情况下
scanf 0.2s
不加的cin 1.9s
加了之后 0.5s
虽然还是比scanf慢,但是比不加实在好太多了。