結果
| 問題 |
No.890 移調の限られた旋法
|
| コンテスト | |
| ユーザー |
tarattata1
|
| 提出日時 | 2019-09-20 23:22:41 |
| 言語 | C++11(廃止可能性あり) (gcc 13.3.0) |
| 結果 |
AC
|
| 実行時間 | 153 ms / 2,000 ms |
| コード長 | 3,292 bytes |
| コンパイル時間 | 1,006 ms |
| コンパイル使用メモリ | 80,732 KB |
| 実行使用メモリ | 18,432 KB |
| 最終ジャッジ日時 | 2024-09-14 20:10:16 |
| 合計ジャッジ時間 | 5,675 ms |
|
ジャッジサーバーID (参考情報) |
judge3 / judge5 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 32 |
コンパイルメッセージ
main.cpp: In function ‘int main(int, char**)’:
main.cpp:122:10: warning: ignoring return value of ‘int scanf(const char*, ...)’ declared with attribute ‘warn_unused_result’ [-Wunused-result]
122 | scanf("%d%d", &n, &k);
| ~~~~~^~~~~~~~~~~~~~~~
ソースコード
#include <stdio.h>
#include <string>
#include <cstring>
#include <stdlib.h>
#include <math.h>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <iterator>
#include <assert.h>
#pragma warning(disable:4996)
typedef long long ll;
#define MIN(a, b) ((a)>(b)? (b): (a))
#define MAX(a, b) ((a)<(b)? (b): (a))
#define LINF 9223300000000000000
#define INF 2140000000
const long long MOD = 1000000007;
using namespace std;
const int max_comb=1000000;
vector<ll> fac(max_comb+1); //n! (mod M)
vector<ll> ifac(max_comb+1); //k!^(-1) (mod M)
ll mpow(ll x, ll n){ //x^n(mod M)
ll ans = 1;
while(n != 0){
if(n&1) ans = ans*x % MOD;
x = x*x % MOD;
n = n >> 1;
}
return ans;
}
ll minv(ll x){
return mpow( x, MOD-2 );
}
ll comb(int a, int b){ // C(a,b) = a! * b!^(-1) * (a-b)^(-1)
if(a == 0 && b == 0)return 1;
if(a < b || a < 0)return 0;
ll tmp = ifac[a-b]* ifac[b] % MOD;
return tmp * fac[a] % MOD;
}
ll perm(int a, int b){ // P(a,b) = a! * (a-b)!^(-1)
if(b == 0)return 1;
if(a < b || a < 0)return 0;
ll tmp = ifac[a-b] % MOD;
return tmp * fac[a] % MOD;
}
void pre_comb()
{
fac[0] = 1;
ifac[0] = 1;
for(int i = 0; i<max_comb; i++){
fac[i+1] = fac[i]*(i+1) % MOD; // n!(mod M)
ifac[i+1] = ifac[i]*minv(i+1) % MOD; // k!^(-1) (mod M)
}
return;
}
ll gcd(ll a, ll b) {
if(b == 0) return a;
return gcd(b,a%b);
}
ll lcm(ll a, ll b) {
ll g = gcd(a,b);
return a / g * b; // Be careful not to overflow
}
vector<int> pp;
void preparePrime( int maxp )
{
int i;
vector<int> a(maxp+1);
for(i=2; i<=maxp; i++) {
int k=i+i;
while(k<=maxp) {
a[k]=1;
k+=i;
}
}
for(i=2; i<=maxp; i++) {
if(a[i]==0) pp.push_back( i );
}
return;
}
void decompositPrime( ll a, vector<pair<ll,ll> >& vv )
{
preparePrime( (int)sqrt((double)a)+1 );
int i;
for(i=0; i<(int)pp.size(); i++) {
int count = 0;
while(a % pp[i] == 0 ) {
a /= pp[i];
count ++;
}
if(count>0) vv.push_back( make_pair( pp[i], count ) );
if (a==1) break;
}
if(a>1) {
vv.push_back( make_pair( a, 1 ) );
}
return;
}
int main(int argc, char* argv[])
{
int n,k;
scanf("%d%d", &n, &k);
int m = gcd(n,k);
if(m==1) {
if(n==k) {
if(n==1) {
printf("0\n"); return 0;
}
printf("1\n"); return 0;
}
else {
printf("0\n"); return 0;
}
}
pre_comb();
vector<pair<ll,ll> > vv;
decompositPrime(m, vv);
ll ans=0;
int siz=(int)vv.size();
int i,j;
for(i=0; i<(1<<siz); i++) {
int tmp=1;
int cnt=0;
for(j=0; j<siz; j++) {
if(i & (1<<j)) {
tmp*=vv[j].first;
cnt++;
}
}
if(tmp==1) continue;
int n0=n/tmp;
int k0=k/tmp;
if(cnt%2) {
ans = (ans + comb(n0, k0)) %MOD;
}
else {
ans = (ans + MOD - comb(n0, k0)) %MOD;
}
}
printf("%lld\n", ans);
return 0;
}
tarattata1