Next K Permutation
3457: Next K Permutation
时间限制: 1 Sec 内存限制: 128 MB提交: 4 解决: 4
[提交] [状态] [讨论版] [命题人:admin]
题目描述
n 个数有 n! 种全排列情况,对所有排列排序后求第 L 个到第 R 个排列中逆序对数量之和。
逆序对定义(摘自 wiki):
设 A 为一个有 n 个数字的有序集 (n>1),其中所有数字各不相同。
如果存在正整数 i,j 使得 1≤i<j≤n 而且 Ai>Aj,则 (Ai,Aj) 这一个有序对称为 A 的一个逆序对,也称作逆序。逆序对的数量称作逆序数。
逆序对定义(摘自 wiki):
设 A 为一个有 n 个数字的有序集 (n>1),其中所有数字各不相同。
如果存在正整数 i,j 使得 1≤i<j≤n 而且 Ai>Aj,则 (Ai,Aj) 这一个有序对称为 A 的一个逆序对,也称作逆序。逆序对的数量称作逆序数。
输入
第一行 case 数量 T。
接下来每一行有 3 个数,n,L,R (3≤n≤12,1≤L≤R≤109)。
接下来每一行有 3 个数,n,L,R (3≤n≤12,1≤L≤R≤109)。
输出
输出逆序对总数。
样例输入
3
3 3 5
6 720 720
8 14625 17743
样例输出
5
15
38745
提示
样例 1 说明:
3 个数所有排列排序后及其逆序对个数:
(1,2,3): 0;
(1,3,2): 1;
(2,1,3): 1;
(2,3,1): 2;
(3,1,2): 2;
(3,2,1): 3.
第 3 个到第 5 个排列逆序对数量之和为 1+2+2=5。
来源/分类
题解:详见代码!!!
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 ll jie_cheng[20],ni_xu_shu[20]; 5 void init() 6 { 7 jie_cheng[0]=ni_xu_shu[0]=ni_xu_shu[1]=0; 8 jie_cheng[1]=1; 9 for(ll i=2;i<=12;i++) 10 { 11 jie_cheng[i]=jie_cheng[i-1]*i; 12 ni_xu_shu[i]=jie_cheng[i-1]*((i-1)*i/2)+ni_xu_shu[i-1]*i;//长度为i的序列(每个数字都不同)所有排列的逆序数总和 13 } 14 } 15 ll solve(int n,ll k) 16 { 17 ll res=0; 18 int prefix[20]; 19 for(int i=1;i<=n;i++)//枚举前缀长度 20 { 21 for(int j=1;j<=n;j++)//枚举前缀元素 22 { 23 bool flag=true; 24 for(int s=1;s<i;s++) 25 { 26 if(prefix[s]==j)//出现过的元素就不能再出现 27 { 28 flag=false; 29 break; 30 } 31 } 32 if(!flag) continue; 33 prefix[i]=j; 34 if(k<jie_cheng[n-i]) break; 35 else 36 { 37 k-=jie_cheng[n-i]; 38 res+=ni_xu_shu[n-i]; 39 ll cnt=0; 40 for(int s=1;s<=i;s++) 41 { 42 for(int l=s+1;l<=i;l++) 43 { 44 if(prefix[s]>prefix[l]) 45 { 46 cnt++; 47 } 48 } 49 } 50 int tmp[20]; 51 for(int s=0;s<=n;s++) tmp[s]=0; 52 for(int s=1;s<=i;s++) tmp[prefix[s]]=1; 53 for(int s=1;s<=n;s++) 54 { 55 for(int l=1;l<=s;l++) 56 { 57 if(tmp[s]==1 && tmp[l]==0) 58 cnt++; 59 } 60 } 61 res+=jie_cheng[n-i]*cnt; 62 } 63 } 64 } 65 return res; 66 } 67 int main() 68 { 69 init(); 70 int t; 71 scanf("%d",&t); 72 while(t--) 73 { 74 int n; 75 ll l,r; 76 scanf("%d %lld %lld",&n,&l,&r); 77 printf("%lld\n",solve(n,r)-solve(n,l-1)); 78 } 79 return 0; 80 }