Submission #1323835

#TimeUsernameProblemLanguageResultExecution timeMemory
1323835ayhabdb2aanazh2tSkyscraper (JOI16_skyscraper)C++20
100 / 100
203 ms260612 KiB
#include <bits/stdc++.h>
#include <cstddef>
using namespace std;
typedef long long ll;

#ifdef LOCAL
#include "algo/debug.h"
#else
#define debug(...) 42
#endif

template < int MOD = 1000000007, typename T = ll > struct ModInt {
    T val;
    ModInt(T V = 0) : val(V) { val %= MOD; }
    ModInt& operator += (const ModInt& rhs) {
        if ((val += rhs.val) >= MOD) val -= MOD;
        return *this;
    }
    ModInt& operator += (const T rhs) {
        if ((val += rhs) >= MOD) val -= MOD;
        return *this;
    }

    ModInt& operator -= (const ModInt& rhs) { 
        if ((val += MOD - rhs.val) >= MOD) val -= MOD; 
        return *this; 
    }
    ModInt& operator -= (const T rhs) { 
        if ((val += MOD - rhs) >= MOD) val -= MOD; 
        return *this; 
    }

    ModInt& operator *= (const ModInt& rhs) { val = (1ll * val * rhs.val) % MOD; return *this; }
    ModInt& operator *= (const T rhs) { val = (1ll * val * rhs) % MOD; return *this; }

    ModInt& operator /= (const ModInt& rhs) { return *this *= rhs.inverse(); }
    ModInt& operator /= (const T rhs) { return *this *= ModInt(rhs).inverse(); }

    ModInt& operator %= (const ModInt& rhs) { val %= rhs.val; return *this; }
    ModInt& operator %= (const T rhs) { val %= rhs; return *this; }

    ModInt& operator ++() { return *this += 1; }
    ModInt& operator --() { return *this -= 1; }
 
    ModInt operator + (const ModInt& rhs) const { ModInt res(*this); return res += rhs; }
    ModInt operator + (const T rhs) const { ModInt res(*this); return res += rhs; }

    ModInt operator % (const ModInt& rhs) const { ModInt res(*this); return res %= rhs; }
    ModInt operator % (const T rhs) const { ModInt res(*this); return res %= rhs; }

    ModInt operator - (const ModInt& rhs) const { ModInt res(*this); return res -= rhs; }
    ModInt operator - (const T rhs) const { ModInt res(*this); return res -= rhs; }

    ModInt operator * (const ModInt& rhs) const { ModInt res(*this); return res *= rhs; }
    ModInt operator * (const T rhs) const { ModInt res(*this); return res *= rhs; }

    ModInt operator / (const ModInt& rhs) const { ModInt res(*this); return res /= rhs; }
    ModInt operator / (const T rhs) const { ModInt res(*this); return res /= rhs; }

    ModInt& operator = (const ModInt& rhs) { val = rhs.val; return *this; }
    ModInt& operator = (const T rhs) { val = rhs; return *this; }

    T operator ~ () { return ~val; }
    bool operator ! () { return !val; }

    bool operator == (const ModInt& rhs) const { return val == rhs.val; }
    bool operator == (const T rhs) const { return val == rhs; }

    bool operator != (const ModInt& rhs) const { return val != rhs.val; }
    bool operator != (const T rhs) const { return val != rhs; }

    bool operator < (const ModInt& rhs) const { return val < rhs.val; }
    bool operator < (const T rhs) const { return val < rhs; }

    bool operator <= (const ModInt& rhs) const { return val <= rhs.val; }
    bool operator <= (const T rhs) const { return val <= rhs; }

    bool operator > (const ModInt& rhs) const { return val > rhs.val; }
    bool operator > (const T rhs) const { return val > rhs; }

    bool operator >= (const ModInt& rhs) const { return val >= rhs.val; }
    bool operator >= (const T rhs) const { return val >= rhs; }

    T operator () () const { return val; }
    ModInt inverse() const { return power(MOD - 2); }

    ModInt power(T n) const {
        ModInt a = *this, res = 1;
        while (n > 0) {
            if (n & 1) res *= a;
            a *= a, n >>= 1;
        }
        return res;
    }

    ModInt power(ModInt n) const {
        ModInt a = *this, res = 1;
        T e = n();
        while (e > 0) {
            if (e & 1) res *= a;
            a *= a, e >>= 1;
        }
        return res;
    }

    friend ModInt operator ^ (ModInt rhs, T n) { return rhs.power(n); }
    friend ModInt operator ^ (ModInt rhs, ModInt n) { return rhs.power(n); }

    friend istream& operator>>(std::istream& is, ModInt& x) noexcept { return is >> x.val; }
    friend ostream& operator<<(std::ostream& os, const ModInt& x) noexcept { return os << x.val; }
};
using Mint = ModInt<>;
int n,l;
int a[105];
Mint dp[105][105][1005][3];

Mint go(int i = 0,int j = 0,int cost = 0,int ends = 0) {
    if(cost > l or j < 0)
        return 0;
    if(i == n)
        return j == 1 and ends == 2;
    auto &ret = dp[i][j][cost][ends];
    if(~ret)
        return ret;
    ret = 0;
    int delta = (i + 1 < n) ? a[i+1] - a[i]:0;
    // new comp
    ret += go(i + 1,j + 1,cost + delta * (2 * (j + 1) - ends),ends); 
    // append
    ret += go(i + 1,j,cost + delta *(2 * j - ends),ends ) * (2 * j - ends); 
    // merge
    if(j >= 2) {
        ll ways = (i == n - 1 and ends == 2) ? 1 : (ll)(j - 1) * (j - ends);
        if(ways > 0) ret += go(i + 1,j - 1,cost + delta * (2*(j-1) - ends),ends) * ways;
    }
    // ends shit
    if(ends < 2) {// place at end, attach at end
        ret += go(i + 1, j + 1,cost + delta * (2 * (j + 1) - (ends + 1)), ends + 1) * (2 - ends);
        if(j) {
            ll ways = (i == n - 1) ? (ll)(2 - ends) * j : (ll)(2 - ends) * (j - ends);
            if(ways > 0) ret += go(i + 1,j, cost + delta * (2 * j - (ends + 1)),ends + 1) * ways;
        }
    }
    return ret;
}

// Pen and paper dipshit.
signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
  
    cin >> n >> l;
    for(int i = 0;i < n;i++)
        cin >> a[i];
    if(n == 1)
        return cout << 1 << '\n',0;
    sort(a,a + n);
    memset(dp,-1,sizeof dp);
    cout << go() << '\n';
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...