結果

問題 No.117 組み合わせの数
ユーザー koyumeishikoyumeishi
提出日時 2015-01-05 01:11:38
言語 C++11
(gcc 11.4.0)
結果
AC  
実行時間 383 ms / 5,000 ms
コード長 2,126 bytes
コンパイル時間 881 ms
コンパイル使用メモリ 77,280 KB
実行使用メモリ 19,072 KB
最終ジャッジ日時 2023-09-03 21:56:51
合計ジャッジ時間 1,860 ms
ジャッジサーバーID
(参考情報)
judge11 / judge15
このコードへのチャレンジ(β)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 383 ms
19,072 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <vector>
#include <cstdio>
#include <sstream>
#include <map>
#include <string>
#include <algorithm>
#include <queue>
#include <cmath>

using namespace std;


#define MOD 1000000007
#define MAX_NUM 2000100

long long fact[MAX_NUM+1];

void init(){
	fact[0] = 1;
	for(int i=1; i<=MAX_NUM; i++){
		fact[i] = ((long long)fact[i-1]*i%MOD)%MOD;
	}
}

long long extgcd(long long a, long long b, long long &x, long long &y){
	long long d=a;
	if(b!=0){
		d = extgcd(b, a%b, y, x);
		y -= (a/b) * x;
	}else{
		x = 1;
		y = 0;
	}
	return d;
}

long long mod_inverse(long long a, long long m){
	long long x,y;
	extgcd(a,m,x,y);
	return (m+x%m)%m;
}

long long mod_fact(long long n, long long p, long long &e){
	e = 0;
	if(n==0) return 1;
	if(n<0) return -1;

	long long res = mod_fact(n/p, p, e);
	e += n/p;

	if(n/p %2 != 0) return res * (p-fact[n%p]) %p;
	return res * fact[n%p]%p;
}

long long mod_comb(long long n, long long k, long long p){
	if(n<0 || k<0 || n<k) return 0;
	long long e1,e2,e3;
	long long a1 = mod_fact(n,p,e1);
	long long a2 = mod_fact(k,p,e2);
	long long a3 = mod_fact(n-k,p,e3);

	if(e1 > e2+e3) return 0;
	return a1 * mod_inverse(a2*a3 %p, p) %p;
}

long long mod_rep(long long n, long long k, long long p){
	if(n<0 || k<0 || n<k) return 0;
	long long e1,e3;
	long long a1 = mod_fact(n,p,e1);
	long long a3 = mod_fact(n-k,p,e3);

	if(e1 > e3) return 0;
	return a1 * mod_inverse(a3 %p, p) %p;
}

int main(){
	
	init();
	
	int T;
	cin >> T;
	for(int t=0; t<T; t++){
		string s;
		cin >> s;
		string sub = s.substr(2, s.size()-2);
		
		string n_s = sub.substr(0, sub.find(','));
		string k_s = sub.substr(sub.find(',')+1, string::npos);

		
		int n,k;
		{
			stringstream ss;
			ss << n_s;
			ss >> n;
		}
		{
			stringstream ss;
			ss << k_s;
			ss >> k;
		}

		if(k==0){
			printf("%d\n", 1);
			continue;
		}
		if(n==0){
			printf("%d\n", 0);
			continue;
		}
		
		if(s[0] == 'P'){
			printf("%lld\n", mod_rep(n,k, MOD) );
		}else if(s[0] == 'C'){
			
			printf("%lld\n", mod_comb(n,k, MOD) );
		}else if(s[0] == 'H'){
			printf("%lld\n", mod_comb(n+k-1,k, MOD));
		}
	}
	return 0;
}
0