結果
| 問題 |
No.916 Encounter On A Tree
|
| コンテスト | |
| ユーザー |
noisy_noimin
|
| 提出日時 | 2019-10-31 17:08:03 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 14 ms / 2,000 ms |
| コード長 | 1,421 bytes |
| コンパイル時間 | 545 ms |
| コンパイル使用メモリ | 67,328 KB |
| 実行使用メモリ | 11,776 KB |
| 最終ジャッジ日時 | 2024-09-14 22:05:48 |
| 合計ジャッジ時間 | 2,512 ms |
|
ジャッジサーバーID (参考情報) |
judge2 / judge4 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 5 |
| other | AC * 56 |
ソースコード
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
constexpr ll MOD = 1000000007;
constexpr int N_MAX = 1 << 20;
ll fact[N_MAX+1];
void init(ll n){
fact[0] = fact[1] = 1;
for(int i=2;i<=n;++i) {
fact[i] = (fact[i-1] * (ll)i) % MOD;
ll k = MOD-2;
ll a = fact[i];
while(k > 0){
a *= a;
a %= MOD;
k >>= 1;
}
}
}
int main() {
ll d, l, r, k;
cin >> d >> l >> r >> k;
init(1LL << d);
ll ld = 0, rd = 0;
while((1LL << (ld+1)) <= l) ++ld;
while((1LL << (rd+1)) <= r) ++rd;
if(ld+rd > 2*d) {
cout << 0 << endl;
return 0;
}
ll lca_d = 0;
while(ld+rd - 2*lca_d > k && lca_d <= min(ld, rd)) {
++lca_d;
}
if(ld+rd - 2*lca_d != k) {
cout << 0 << endl;
return 0;
}
ll ans = 0;
// l と r の置き方
if(ld == lca_d) {
ans = (((1LL << (rd-ld)) % MOD) * ((1LL << ld)) % MOD) % MOD;
} else {
ans = (((1LL << (rd-lca_d-1)) % MOD) * ((1LL << (ld-lca_d-1))) % MOD) % MOD;
ans = (ans * ((1LL << lca_d)) % MOD) % MOD;
(ans *= 2LL) %= MOD;
}
// その他の数字の置き方
for(int i=0;i<d;++i) {
ll n = 1LL << i;
if(ld == i) --n;
if(rd == i) --n;
ans *= fact[n];
ans %= MOD;
}
cout << ans << endl;
}
noisy_noimin