ARC 009 C
問題概要
Nコのポストに手紙を届ける。Kコの手紙だけ正しくないポストに届き、すべてのポストに手紙が1コずつ届く。このとき、ポストと手紙の対応関係は mod 1777777777 (素数) で何通りか。(2 <= N <= 1e18, 2 <= K <= 1e6)
- ヒント1
正しく届かない手紙・ポストの集合を固定して考える。
- ヒント2
正しく届かない手紙・ポストの集合は K なので、まずは N = K の場合で解くことを考える。
すると、ポスト・手紙がそれぞれ K コあり、どれも正しく届かない届き方のが何通りあるのか計算する問題になる。
これは、正しく届く手紙の集合に関する包除原理で計算することができる。
#define N 2000000 ll inv[N], fact[N], ifact[N], be[N]; ll comb(ll a, ll b){ return fact[a+b]*ifact[a]%mod*ifact[b]%mod; } ll comb_nk(ll n, ll k){ return comb(n-k, k); } ll pow_mod(ll a, ll r, ll m){ ll x = 1; while(r){ if(r&1) (x*=a)%=m; (a*=a)%=m; r>>=1; } return x; } void init_fact(ll n = N){ inv[1] = 1; for(int i = 2; i < n; i++) inv[i] = inv[mod%i] * (mod - mod/i) % mod; fact[0] = ifact[0] = 1; for(int i = 1; i < n; i++){ fact[i] = (fact[i-1]*i)%mod; ifact[i]=(ifact[i-1]*inv[i])%mod; } } int main(){ init_fact(); ll n, k; cin>>n>>k; ll res = 0; rep(i, k+1){ (res+=fact[k-i]*comb_nk(k, i)%mod*(i%2?-1:1))%=mod; } (res*=ifact[k])%=mod; rep(i, k) (res*=(n-i)%mod)%=mod; res += mod; cout<<res%mod<<endl; return 0; }