compro-library

This documentation is automatically generated by online-judge-tools/verification-helper

View the Project on GitHub ningenMe/compro-library

:heavy_check_mark: test/math/CombinationMod-factorial.test.cpp

Depends on

Code

#define PROBLEM "https://yukicoder.me/problems/no/916"

#include <vector>
#include <iostream>
using namespace std;
#include "../../lib/30-math/CombinationMod.cpp"
#include "../../lib/00-util/ModInt.cpp"
constexpr long long MOD = 1000'000'007;
using modint = ModInt<MOD>;

int main(void){
	int d, l, r, k;
    int MAX_d = 20;
	cin >> d >> l >> r >> k;
    CombinationMod<MOD> CM((1<<MAX_d));
    vector<int> sum(MAX_d + 1, 0);
	vector<long long> pow2(MAX_d + 1,1);
	for (int i = 2; i <= MAX_d; ++i) pow2[i] = (pow2[i - 1] * 2) % MOD;
	for (int i = 1; i < MAX_d + 1; ++i) sum[i] = sum[i - 1] + pow2[i];
	l = lower_bound(sum.begin(), sum.end(), l) - sum.begin();
	r = lower_bound(sum.begin(), sum.end(), r) - sum.begin();

	int lca = -1;
	if ((l + r - k) > 1 && (l + r - k) % 2 == 0) lca = (l + r - k) / 2;
	if(lca == -1 || lca > l || lca > r){
		cout << 0 << endl;
		return 0;
	}
	modint ans = 1;
	for (int i = 1; i <= d; ++i) {
		int cnt = pow2[i];
		if (i == l) cnt--;
		if (i == r) cnt--;
		ans *= CM.factorial(cnt);
	}
	ans *= pow2[lca];
	ans *= pow2[l - lca];
	ans *= pow2[r - lca];
	ans *= 2;

	cout << ans << endl;
	return 0;}
#line 1 "test/math/CombinationMod-factorial.test.cpp"
#define PROBLEM "https://yukicoder.me/problems/no/916"

#include <vector>
#include <iostream>
using namespace std;
#line 1 "lib/30-math/CombinationMod.cpp"
/*
 * @title CombinationMod - mod上の二項係数・階乗
 * @docs md/math/CombinationMod.md
 */
template<long long mod> class CombinationMod {
    vector<long long> fac,finv,inv;
public:
    CombinationMod(int N) : fac(N + 1), finv(N + 1), inv(N + 1) {
        fac[0] = fac[1] = finv[0] = finv[1] = inv[1] = 1;
        for (int i = 2; i <= N; ++i) {
            fac[i] = fac[i - 1] * i % mod;
            inv[i] = mod - inv[mod%i] * (mod / i) % mod;
            finv[i] = finv[i - 1] * inv[i] % mod;
        }
    }
    inline long long binom(int n, int k) {
        return ((n < 0 || k < 0 || n < k) ? 0 : fac[n] * (finv[k] * finv[n - k] % mod) % mod);
    }
    inline long long factorial(int n) {
        return fac[n];
    }
};

//verify https://atcoder.jp/contests/abc021/tasks/abc021_d
#line 1 "lib/00-util/ModInt.cpp"
/*
 * @title ModInt
 * @docs md/util/ModInt.md
 */
template<long long mod> class ModInt {
public:
    long long x;
    constexpr ModInt():x(0) {}
    constexpr ModInt(long long y) : x(y>=0?(y%mod): (mod - (-y)%mod)%mod) {}
    constexpr ModInt &operator+=(const ModInt &p) {if((x += p.x) >= mod) x -= mod;return *this;}
    constexpr ModInt &operator+=(const long long y) {ModInt p(y);if((x += p.x) >= mod) x -= mod;return *this;}
    constexpr ModInt &operator+=(const int y) {ModInt p(y);if((x += p.x) >= mod) x -= mod;return *this;}
    constexpr ModInt &operator-=(const ModInt &p) {if((x += mod - p.x) >= mod) x -= mod;return *this;}
    constexpr ModInt &operator-=(const long long y) {ModInt p(y);if((x += mod - p.x) >= mod) x -= mod;return *this;}
    constexpr ModInt &operator-=(const int y) {ModInt p(y);if((x += mod - p.x) >= mod) x -= mod;return *this;}
    constexpr ModInt &operator*=(const ModInt &p) {x = (x * p.x % mod);return *this;}
    constexpr ModInt &operator*=(const long long y) {ModInt p(y);x = (x * p.x % mod);return *this;}
    constexpr ModInt &operator*=(const int y) {ModInt p(y);x = (x * p.x % mod);return *this;}
    constexpr ModInt &operator^=(const ModInt &p) {x = (x ^ p.x) % mod;return *this;}
    constexpr ModInt &operator^=(const long long y) {ModInt p(y);x = (x ^ p.x) % mod;return *this;}
    constexpr ModInt &operator^=(const int y) {ModInt p(y);x = (x ^ p.x) % mod;return *this;}
    constexpr ModInt &operator/=(const ModInt &p) {*this *= p.inv();return *this;}
    constexpr ModInt &operator/=(const long long y) {ModInt p(y);*this *= p.inv();return *this;}
    constexpr ModInt &operator/=(const int y) {ModInt p(y);*this *= p.inv();return *this;}
    constexpr ModInt operator=(const int y) {ModInt p(y);*this = p;return *this;}
    constexpr ModInt operator=(const long long y) {ModInt p(y);*this = p;return *this;}
    constexpr ModInt operator-() const {return ModInt(-x); }
    constexpr ModInt operator++() {x++;if(x>=mod) x-=mod;return *this;}
    constexpr ModInt operator--() {x--;if(x<0) x+=mod;return *this;}
    constexpr ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }
    constexpr ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }
    constexpr ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }
    constexpr ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }
    constexpr ModInt operator^(const ModInt &p) const { return ModInt(*this) ^= p; }
    constexpr bool operator==(const ModInt &p) const { return x == p.x; }
    constexpr bool operator!=(const ModInt &p) const { return x != p.x; }
    // ModInt inv() const {int a=x,b=mod,u=1,v=0,t;while(b > 0) {t = a / b;swap(a -= t * b, b);swap(u -= t * v, v);} return ModInt(u);}
    constexpr ModInt inv() const {int a=x,b=mod,u=1,v=0,t=0,tmp=0;while(b > 0) {t = a / b;a-=t*b;tmp=a;a=b;b=tmp;u-=t*v;tmp=u;u=v;v=tmp;} return ModInt(u);}
    constexpr ModInt pow(long long n) const {ModInt ret(1), mul(x);for(;n > 0;mul *= mul,n >>= 1) if(n & 1) ret *= mul;return ret;}
    friend ostream &operator<<(ostream &os, const ModInt &p) {return os << p.x;}
    friend istream &operator>>(istream &is, ModInt &a) {long long t;is >> t;a = ModInt<mod>(t);return (is);}
};
constexpr long long MOD_998244353 = 998244353;
constexpr long long MOD_1000000007 = 1'000'000'000LL + 7; //'
#line 8 "test/math/CombinationMod-factorial.test.cpp"
constexpr long long MOD = 1000'000'007;
using modint = ModInt<MOD>;

int main(void){
	int d, l, r, k;
    int MAX_d = 20;
	cin >> d >> l >> r >> k;
    CombinationMod<MOD> CM((1<<MAX_d));
    vector<int> sum(MAX_d + 1, 0);
	vector<long long> pow2(MAX_d + 1,1);
	for (int i = 2; i <= MAX_d; ++i) pow2[i] = (pow2[i - 1] * 2) % MOD;
	for (int i = 1; i < MAX_d + 1; ++i) sum[i] = sum[i - 1] + pow2[i];
	l = lower_bound(sum.begin(), sum.end(), l) - sum.begin();
	r = lower_bound(sum.begin(), sum.end(), r) - sum.begin();

	int lca = -1;
	if ((l + r - k) > 1 && (l + r - k) % 2 == 0) lca = (l + r - k) / 2;
	if(lca == -1 || lca > l || lca > r){
		cout << 0 << endl;
		return 0;
	}
	modint ans = 1;
	for (int i = 1; i <= d; ++i) {
		int cnt = pow2[i];
		if (i == l) cnt--;
		if (i == r) cnt--;
		ans *= CM.factorial(cnt);
	}
	ans *= pow2[lca];
	ans *= pow2[l - lca];
	ans *= pow2[r - lca];
	ans *= 2;

	cout << ans << endl;
	return 0;}
Back to top page