POJ 3761 Bubble Sort

来源:互联网 发布:倩丽口红知乎 编辑:程序博客网 时间:2024/05/14 05:42

POJ   3761   Bubble Sort                   题目链接:http://poj.org/problem?id=3761

                                             

题目大意:要用冒泡排序给一个长度为n的数列排序(n给出,无重复元素),问恰好k次排好的原排列个数有多少种。

题目分析:网上的解释总感觉不大全,我就把我卡住的地方着重说一下吧。给出了n和k后,可以把数组分成两个部分,上k个数和下n-k个数。上k个数怎么排也不可能达到k个逆序数了,所以暂时忽略它们的顺序,将它们随意摆放后开始把下n-k个数向其中插,这样做可以得到幂的算法(因为每次插入一个数后对下一个数没有影响[更大的数必须排在更小的数右边,不然逆序数可能会出现大于k的])。这种计算幂的方法可以帮我们得到逆序数是Σ(从1~m的),而我们需要逆序数是k的,那么就可以计算1~k和1~(k-1)的,一减就是结果。

code:

#include<stdio.h>#define MOD 20100713#define K 1000010int fac[K];void init(){fac[0]=1;for(long long i=1;i<K;i++){fac[i]=(i*fac[i-1])%MOD;}}long long quickPow(long long a,long long b){if(b==0)return 1;if(b==1)return a;long long t=quickPow(a,b/2);t=(t*t)%MOD;if(b&1)return (t*a)%MOD;else return t;}long long solve(int n,int k){long long res=fac[k]*(quickPow(k+1,n-k)-quickPow(k,n-k))%MOD;if(res<0)return res+MOD;else return res;}int main(){int tt,n,k;scanf("%d",&tt);init();while(tt--){scanf("%d%d",&n,&k);printf("%lld\n",solve(n,k));}return 0;}

PS:老师给讲的这题,讲的很清楚,过了一天自己也差不多能推出来。最大的收获在于见识了一道较复杂题的推理过程,其次就是学习了快速幂的算法,二分思想果然屡试不爽…也差点被自己弄崩溃了,边界一百万写成了十万居然白交了十四遍没有发现…


PSS:参考过这一篇http://www.cnblogs.com/Wizmann/archive/2012/05/12/2496860.html




0 0