逆序对神题

   

/*
    一个大暴力
*/
#include<iostream>
#include<cstdio>
using namespace std;
#define maxn 100010
long long n,m,a[maxn],b[maxn],temp[maxn],tot,ans,Len;
void sor(long long l,long long r)
{
    if(l==r)return ;
    long long mid=(l+r)/2;
    sor(l,mid);
    sor(mid+1,r);
    long long i=l,p=l,j=mid+1;
    while(i<=mid&&j<=r)
    {
        if(b[i]>b[j])tot+=mid-i+1,temp[p++]=b[j++];
        else temp[p++]=b[i++];
    }
    while(i<=mid)temp[p++]=b[i++];
    while(j<=r)temp[p++]=b[j++];
    for(long long i=l;i<=r;i++)b[i]=temp[i];
}
bool check(long long l,long long r){
    sor(l,r);
    if(tot<=m)return 1;
    else return 0;
}
void prepare(long long l,long long r){
    long long len=n-(r-l-1);
    long long i=0;
    Len=0;
    for(long long i=1;i<=l;i++)b[++Len]=a[i];
    for(long long i=r;i<=n;i++)b[++Len]=a[i];
}
int main(){
    //freopen("Cola.txt","r",stdin);
    scanf("%lld%lld",&n,&m);
    for(long long i=1;i<=n;i++){
        scanf("%lld",&a[i]);
        b[i]=a[i];
    }
    tot=0;prepare(0,1);
    if(check(1,n)){
        ans=((n-1)*n)/2;//区间大小为n的方案总数 
        printf("%lld",ans); 
        return 0;
    }
    for(long long l=1;l<=n-2;l++){
        for(long long r=l+2;r<=n;r++){
            tot=0;prepare(l,r);
            sor(1,Len);
            if(tot<=m)ans++;
        }
    }
    printf("%lld",ans); 
    return 0;
}
原文地址:https://www.cnblogs.com/thmyl/p/7216740.html