省选专练ZJOI2011看电影

高精度+组合数学
#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
/*
先加上一个位置并看成一个环,那么方案数就是(K+1)^n,并且可以保证一定合法,因为是环,又因为是环可以转有K+1个方案重复了,所以实际上是(K+1)^n-1。 
拆掉一个空座位回到原问题,因为是空位,所以一定没有人跨过去,任何一个空位都可拆,那么拆的方案数是K+1-n
*/
int GCD(int x,int y){
	if(y==0)
		return x;
	else
		return GCD(y,x%y);
}
const int Mod=1e5; 
struct Make_Int{
	int a[20000];
	Make_Int(int x=0){
		memset(a,0,sizeof(a));
		a[++a[0]]=x;
	}
	Make_Int &operator *=(int t){
		for(int i=1;i<=a[0];i++){
			a[i]*=t;
		}
		for(int i=1;i<=a[0]+10;i++){
			a[i+1]+=a[i]/Mod;
			a[i]%=Mod;
		}
		for(int i=a[0]+10;;i--){
			if(a[i]){
				a[0]=i;
				return *this;
			}		
		}
	}
	void print(){
		printf("%d",a[a[0]]);
		for(int i=a[0]-1;i>=1;i--)
			printf("%05d",a[i]);
	}
}A,B;
int main(){
	int T;
	scanf("%d",&T); 
	while(T--){
		int n,k; 
		scanf("%d%d",&n,&k);
		if(k<n){
			printf("0 1\n");
			continue;
		}
			
		A=Make_Int(1);
		B=Make_Int(1);
		int x=k+1-n;
		for(int i=1;i<=n-1;i++){
			int g=GCD(k,x);
			x/=g;
			A*=k+1;
			B*=k/g; 
		}
		int g=GCD(k,x);
		x/=g;
		A*=x;
		B*=k/g; 
		A.print();
		printf(" ");
		B.print();
		printf("\n");
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值