游戏(结论)(逆序对)


其实稍微思考一下就知道这个题的实质是求逆序对数量。可以用树状数组写,也可以用归并排序写。

其实看起来数据范围是需要写高精度的,但是。。。。数据造锅了。。所以。。。我的辣鸡非高精程序竟然也A了。。赛后有点懒,就不补高精度了。

大家知道是水题就行了。

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,tree[500010];
long long B;
void add(int k,int num)
{
    while(k<=n)
    {tree[k]+=num;k+=k&-k;}
}
int read(int k)
{
    int sum=0;
    while(k){sum+=tree[k];k-=k&-k;}
    return sum;
}
struct node{int val,pos;}a[500010];
bool cmp(node a,node b){return a.val<b.val;}
int main()
{
    freopen("game.in","r",stdin);
    freopen("game.out","w",stdout);
	int i,j;
    int b[500010];
    scanf("%d%lld",&n,&B);
    memset(tree,0,sizeof(tree));
    for(i=1;i<=n;i++)
    {
           scanf("%d",&a[i].val);
           a[i].pos=i;
    }
    sort(a+1,a+1+n,cmp);
    int cnt=1;
    for(i=1;i<=n;i++)
    {
        if(i!=1&&a[i].val!=a[i-1].val)
            cnt++;
        b[a[i].pos]=cnt;
    }
    long long sum=0;
    for(i=1;i<=n;i++)
    {
        add(b[i],1);
        sum+=(i-read(b[i]));
    }
    long long ans;
    if(sum-(B-1)<0&&n!=1)  ans=sum+sum*(sum-1)/2;
    else if(n==1) ans=0;
    else if(B==0) ans=0;
    else  ans=sum*B-B*B/2+B/2;
    cout<<ans<<endl;
    return 0;
}

posted @ 2018-10-14 16:18  风浔凌  阅读(208)  评论(0编辑  收藏  举报