游戏(结论)(逆序对)
其实稍微思考一下就知道这个题的实质是求逆序对数量。可以用树状数组写,也可以用归并排序写。
其实看起来数据范围是需要写高精度的,但是。。。。数据造锅了。。所以。。。我的辣鸡非高精程序竟然也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;
}