20201009 day30 复习4:逆序对 1 归并排序 2 离散化树状数组

#include<cstdio>
#define msort merge_sort
#define ll long long
using namespace std;
const int maxn=5e5+5;
int a[maxn],r[maxn],n;
long long ans=0; 
void msort(int s,int t){
    if(s==t) return ;
    int mid=(s+t)/2;
    msort(s,mid);
	msort(mid+1,t);
    int i=s,j=mid+1,k=s;
    while(i<=mid&&j<=t)
        if(a[i]<=a[j]) r[k]=a[i],k++,i++;//先赋值再+1 
        else r[k]=a[j],k++,j++,ans+=(ll)mid-i+1;//理解为数学归纳
    while(i<=mid) r[k]=a[i],k++,i++;
    while(j<=t) r[k]=a[j],k++,j++;
    for(int i=s;i<=t;i++) a[i]=r[i];
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
	}
    msort(1,n);
    printf("%lld
",ans);
    return 0;
}

2 离散化树状数组

#include<iostream>
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int maxx=1000005;
ll a[maxx],b[maxx],s[maxx];
ll n;
void init()
{
	sort(b+1,b+1+n);
	unique(b+1,b+1+n);//-b-1;
	for(ll i=1;i<=n;i++)
	{
		a[i]=lower_bound(b+1,b+n+1,a[i])-b;
	}
	return;
}
int main()
{
	scanf("%lld",&n);
	for(ll i=1;i<=n;i++)
	{
		scanf("%lld",&a[i]);
		b[i]=a[i];
	}
	ll ans=0;
	init();
	for(ll i=n;i>=1;i--)
	{
		for(ll j=a[i];j<=n;j+=(j&-j))
		{
			s[j]++;
		}
		for(ll j=a[i]-1;j>=1;j-=(j&-j))
		{
			ans+=s[j];
		}
	}
	printf("%lld",ans);	
	return 0;
}
var ens=document.querySelectorAll('.showen'); ens.forEach(function(item,index){ item.onclick=function(){ item.parentNode.nextElementSibling.style.display = "block"; } })