题意:1~n n 个数的全排列,输入其中两组数,输出 rank 差。
思路:预处理每位上一个数字所出现次数,然后对于输入的数,第 i 位前面有 x 个小于 a[i]的数,a[i]-=x.(结果代表个数),做差计算。
#include<iostream>
#include<cmath>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#include<set>
#include<cstdio>
#include<algorithm>
using namespace std;
const int mod = 1e6+7;
int a[105], a1[105], b[105], b1[105], n, ans, num[105];
void init(){
num[0] = 1;
for(int i = 1; i <= 105; i++){
num[i] = num[i-1]*i;
num[i] %= mod;
}
}
int fxxk(int a1[], int a[]){
for(int i = 0; i < n; i++){
scanf("%d", &a1[i]);
a[i] = a1[i];
}
for(int i = 0; i < n; i++){
for(int j = 0; j < i; j++){
if(a1[j] < a1[i])
a[i]--;
}
}
}
int main(){
//freopen("a.txt", "r", stdin);
int T;cin>>T;
init();
for(int cas = 1; cas <= T; cas++){
scanf("%d", &n);
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
fxxk(a1, a);
fxxk(b1, b);
ans = 0;
//确定rank大的减去rank小的
int flag = 0;
for(int i = 0; i < n; i++){
if(a[i] > b[i]){
flag = 1;
break;
}
if(a[i] < b[i]){
flag = 0;
break;
}
}
for(int i = 0; i < n; i++){
if(flag)
a[i] -= b[i];
else a[i] = (b[i]-a[i]);
if(a[i] != 0){
ans += a[i]*num[n-i-1];
ans %= mod;
}
}
//rank确定的情况下,结果一定应该是正的,如果是负的,加上mod再取模。
ans += mod;
ans %= mod;
printf("Case $%d:n%dn", cas, ans);
}
return 0;
}