本文共 1933 字,大约阅读时间需要 6 分钟。
a a a数组是 1 1 1递增到 k k k,然后递减到 k − ( n − k ) k-(n-k) k−(n−k)
实际上数组的后 2 n − 2 k + 1 2n-2k+1 2n−2k+1个元素以 k k k为中心都是对称的
逆序对个数为 2 ∗ [ 1 + 2 + 3... + ( n − k − 1 ) ] + ( n − k ) 2*[1+2+3...+(n-k-1)]+(n-k) 2∗[1+2+3...+(n−k−1)]+(n−k)
化简得到逆序对数量为 ( n − k ) 2 (n-k)^2 (n−k)2
然后看最后 b b b数组的形式,必然是
a [ p 1 ] a [ p 2 ] . . . a [ p k − ( n − k ) ] . . . a [ p k ] . . . a [ p k − ( n − k ) ] a[p_1]\ a[p_2]... a[p_{k-(n-k)}]...\ a[p_k]\ ...a[p_{k-(n-k)}] a[p1] a[p2]...a[pk−(n−k)]... a[pk] ...a[pk−(n−k)]
暂时只观察后面一段长 2 n − 2 k + 1 2n-2k+1 2n−2k+1个对称的数字,设 s u m = 2 n − 2 k + 1 sum=2n-2k+1 sum=2n−2k+1
好,现在来证明 p p p的后 s u m sum sum个对称数字的逆序是固定的
不妨把后面一段对称的数字写成这样的形式比较直观,下面 z h i i zhi_i zhii是互不相同的数
z h i 1 z h i 2 . . . z h i n − k + 1 . . . z h i 2 z h i 1 zhi_1\ zhi_2\ ...\ zhi_{n-k+1}\ ...\ zhi_2\ zhi_1 zhi1 zhi2 ... zhin−k+1 ... zhi2 zhi1
只考虑每个数作为逆序对的前一个数产生的贡献
设第一大的数在第 i d 1 id_1 id1个位置和 s u m − i d 1 + 1 sum-id_1+1 sum−id1+1个位置
第 i d 1 id_1 id1个位置和后面形成 s u m − i d 1 − 1 sum-id_1-1 sum−id1−1个逆序对
第 s u m − i d 1 + 1 sum-id_1+1 sum−id1+1个位置和后面形成 i d 1 − 1 id_1-1 id1−1个逆序对
总共形成 s u m − 2 sum-2 sum−2个逆序对,发现和 i d 1 id_1 id1并没有关系
对于第二大的数在 i d 2 id_2 id2位置,这里需要分 i d 1 id_1 id1在 i d 2 id_2 id2两端讨论一下,不过结果都是形成 s u m − 4 sum-4 sum−4个逆序对
所以后面对称部分内部的逆序对是 ∑ i = 1 n − k ( s u m − 2 ∗ i ) = ( n − k ) 2 \sum\limits_{i=1}^{n-k}(sum-2*i)=(n-k)^2 i=1∑n−k(sum−2∗i)=(n−k)2
惊人的发现!!!仅仅是对称部分,不管 p p p数组是什么样,逆序对都已经和 a a a一样了
意味着前面不对称的部分,也就是当 i ∈ [ 1 , n − s u m ] i\in[1,n-sum] i∈[1,n−sum]时不能和后面产生任何的逆序对,也就是 p i = i p_i=i pi=i
而当 i ∈ [ n − s u m + 1 , n ] i\in[n-sum+1,n] i∈[n−sum+1,n]时,反正怎么放都会产生 ( n − k ) 2 (n-k)^2 (n−k)2个逆序对, p p p数组干脆从大到小放。
至此问题得到解,很遗憾没有在比赛中写出来,也不想去找规律
能够这么巧妙地自己证明出来,我觉得非常开心.
#includeusing namespace std;const int maxn = 2e5+10;int n,k;int main(){ int t; cin >> t; while( t-- ) { cin >> n >> k; int sum = 2*n-2*k+1; for(int i=1;i<=n-sum;i++) cout << i << " "; for(int i=k;i>n-sum;i--) cout << i << " "; cout << endl; }}
转载地址:https://issue-is-vegetable.blog.csdn.net/article/details/112670071 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!