Kleene Inversion
Problem Statement
We have a sequence of N integers A~=~A0,~A1,~…,~AN−1.
Let B be a sequence of K×N integers obtained by concatenating K copies of A. For example, if A~=~1,~3,~2 and K~=~2, B~=~1,~3,~2,~1,~3,~2.
Find the inversion number of B, modulo 109+7.
Here the inversion number of B is defined as the number of ordered pairs of integers (i,~j)~(0≤i<j≤K×N−1) such that Bi>Bj.
Constraints
- All values in input are integers.
- 1≤N≤2000
- 1≤K≤109
- 1≤Ai≤2000
Input
Input is given from Standard Input in the following format:
N K
A0 A1 … AN−1
Output
Print the inversion number of B, modulo 109+7.
Sample Input 1
2 2
2 1
Sample Output 1
3
In this case, B~=~2,~1,~2,~1. We have:
- B0>B1
- B0>B3
- B2>B3
-
Thus, the inversion number of B is 3.
Sample Input 2
3 5 1 1 1
-
Sample Output 2
-
0
A may contain multiple occurrences of the same number.Sample Input 3
10 998244353 10 9 8 7 5 6 3 4 2 1
Sample Output 3
185297239
Be sure to print the output modulo 109+7.
-
题意:求出k循环个n长的序列中,每个元素比后面大的个数之和。
思路:只需要求出第一个n个元素的序列中每个元素之前和之后比他小的个数,之前比他小的个数乘(k-1)的累加,之后比它小的个数乘k的累加。
#include<iostream>
#include<string.h>
using namespace std;
long long n,k;
long long a[1000110],c[1000010],d[1000010];
int main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>k;
long long sum=0;
sum=(k+1)*k/2;
sum-=k;
sum%=1000000007;
for(int i=0;i<n;i++){
cin>>a[i];
}
memset(c,0,sizeof(c));
memset(d,0,sizeof(d));
for(int i=0;i<n;i++){
for(int j=0;j<i;j++){
if(a[i]>a[j]){
c[i]++;
}
}
for(int j=i+1;j<n;j++){
if(a[i]>a[j]){
d[i]++;
}
}
}
long long ans=0;
// cout<<sum<<endl;
for(int i=0;i<n;i++){
// cout<<c[i]<<" "<<d[i]<<endl;
ans+=(c[i]*sum);
ans%=1000000007;
ans+=(d[i]*(sum+k));
ans%=1000000007;
}
cout<<ans<<endl;
return 0;
}