题意:问一个冒泡排序中要交换多少次,其实就是求逆序对的个数。然后开始总是超时,后来用了一个
树来模拟了一下,过了。。。不过之后看别人的,可以用归并排序来求逆序对。
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
int a[1000005];
int b[1000005];
long long ans=0;
void hb(int left,int mid,int right)
{
int r=mid+1,l=left,h=left;//注意这里的left一定要有其他来表示,如果直接改动的话,之后用left就会问题的!
while(l<=mid&&r<=right)
{
if(a[l]<=a[r]) b[h++]=a[l++];//这里不要掉了个=
else {b[h++]=a[r++];ans+=(mid-l+1);}
}
if(l<=mid) for(int i=l;i<=mid;i++) b[h++]=a[i];
else for(int i=r;i<=right;i++) b[h++]=a[i];
for(int i=left;i<=right;i++) a[i]=b[i];
}
void gbpx(int left,int right)
{
while(right>left)
{
int mid=(left+right)/2;
gbpx(left,mid);
gbpx(mid+1,right);
hb(left,mid,right);
return;//这个为什么要加return?
}
}
int main()
{
int n;
scanf("%d",&n);
for(int i=0;i<n;i++)
scanf("%d",&a[i]);
gbpx(0,n-1);
cout<<ans<<endl;
return 0;
}
献上我们的树
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <set>
#include <vector>
#include <map>
#include <queue>
using namespace std;
struct node
{
int w,xd,num;
node *left,*right;
};
node *root;
long long ans=0,sum=0;
void build(node *&t,int x)
{
if(t==NULL)
{
t=new node;
t->left=NULL;
t->right=NULL;
t->w=x;
t->xd=0;
t->num=0;
return ;
}
if(x>t->w)
{
t->num++;
build(t->right,x);
}
else if(x==t->w)
{t->xd++;sum+=(t->num);return ;}//考虑相同的时候
else if(x<t->w)
{
sum+=(t->num)+(t->xd)+1;
build(t->left,x);
}
}
int main()
{
int n;
scanf("%d",&n);
root=new node();
root->num=0;
int a;
scanf("%d",&a);
root->w=a;
root->left=NULL;
root->right=NULL;
root->xd=0;
for(int i=1;i<n;i++)
{
scanf("%d",&a);
sum=0;
build(root,a);
// cout<<sum<<endl;
ans+=sum;
}
cout<<ans<<endl;
return 0;
}