POJ 3761 Bubble Sort

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 1000010
int 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




  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值