Submission #885337

# Submission time Handle Problem Language Result Execution time Memory
885337 2023-12-09T13:21:23 Z CDuong Skyscraper (JOI16_skyscraper) C++17
100 / 100
167 ms 167740 KB
/*
#pragma GCC optimize("Ofast,unroll-loops")
#pragma GCC target("avx2,fma,bmi,bmi2,sse4.2,popcnt,lzcnt")
*/

#include <bits/stdc++.h>
#define taskname ""
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define i64 long long
#define pb push_back
#define ff first
#define ss second
#define isz(x) (int)x.size()
using namespace std;

const int mxN = 2e5 + 5;
// const int mod = 1e9 + 7;
const i64 oo = 1e18;

using uint = unsigned int;
template<uint _mod>
struct modular_fixed_base{
    static constexpr uint mod(){
        return _mod;
    }
    template<class T>
    static vector<modular_fixed_base> precalc_power(T base, int SZ){
        vector<modular_fixed_base> res(SZ + 1, 1);
        for(auto i = 1; i <= SZ; ++ i) res[i] = res[i - 1] * base;
        return res;
    }
    static vector<modular_fixed_base> _INV;
    static void precalc_inverse(int SZ){
        if(_INV.empty()) _INV.assign(2, 1);
        for(auto x = _INV.size(); x <= SZ; ++ x) _INV.push_back(_mod / x * -_INV[_mod % x]);
    }
    // _mod must be a prime
    static modular_fixed_base _primitive_root;
    static modular_fixed_base primitive_root(){
        if(_primitive_root) return _primitive_root;
        if(_mod == 2) return _primitive_root = 1;
        if(_mod == 998244353) return _primitive_root = 3;
        uint divs[20] = {};
        divs[0] = 2;
        int cnt = 1;
        uint x = (_mod - 1) / 2;
        while(x % 2 == 0) x /= 2;
        for(auto i = 3; 1LL * i * i <= x; i += 2){
            if(x % i == 0){
                divs[cnt ++] = i;
                while(x % i == 0) x /= i;
            }
        }
        if(x > 1) divs[cnt ++] = x;
        for(auto g = 2; ; ++ g){
            bool ok = true;
            for(auto i = 0; i < cnt; ++ i){
                if((modular_fixed_base(g).power((_mod - 1) / divs[i])) == 1){
                    ok = false;
                    break;
                }
            }
            if(ok) return _primitive_root = g;
        }
    }
    constexpr modular_fixed_base(): data(){ }
    modular_fixed_base(const double &x){ data = normalize(llround(x)); }
    modular_fixed_base(const long double &x){ data = normalize(llround(x)); }
    template<class T, typename enable_if<is_integral<T>::value>::type* = nullptr> modular_fixed_base(const T &x){ data = normalize(x); }
    template<class T, typename enable_if<is_integral<T>::value>::type* = nullptr> static uint normalize(const T &x){
        int sign = x >= 0 ? 1 : -1;
        uint v =  _mod <= sign * x ? sign * x % _mod : sign * x;
        if(sign == -1 && v) v = _mod - v;
        return v;
    }
    const uint &operator()() const{ return data; }
    template<class T> operator T() const{ return data; }
    modular_fixed_base &operator+=(const modular_fixed_base &otr){ if((data += otr.data) >= _mod) data -= _mod; return *this; }
    modular_fixed_base &operator-=(const modular_fixed_base &otr){ if((data += _mod - otr.data) >= _mod) data -= _mod; return *this; }
    template<class T, typename enable_if<is_integral<T>::value>::type* = nullptr> modular_fixed_base &operator+=(const T &otr){ return *this += modular_fixed_base(otr); }
    template<class T, typename enable_if<is_integral<T>::value>::type* = nullptr> modular_fixed_base &operator-=(const T &otr){ return *this -= modular_fixed_base(otr); }
    modular_fixed_base &operator++(){ return *this += 1; }
    modular_fixed_base &operator--(){ return *this += _mod - 1; }
    modular_fixed_base operator++(int){ modular_fixed_base result(*this); *this += 1; return result; }
    modular_fixed_base operator--(int){ modular_fixed_base result(*this); *this += _mod - 1; return result; }
    modular_fixed_base operator-() const{ return modular_fixed_base(_mod - data); }
    modular_fixed_base &operator*=(const modular_fixed_base &rhs){
        data = (unsigned long long)data * rhs.data % _mod;
        return *this;
    }
    template<class T, typename enable_if<is_integral<T>::value>::type* = nullptr>
    modular_fixed_base &inplace_power(T e){
        if(e < 0) *this = 1 / *this, e = -e;
        modular_fixed_base res = 1;
        for(; e; *this *= *this, e >>= 1) if(e & 1) res *= *this;
        return *this = res;
    }
    template<class T, typename enable_if<is_integral<T>::value>::type* = nullptr>
    modular_fixed_base power(T e) const{
        return modular_fixed_base(*this).inplace_power(e);
    }
    modular_fixed_base &operator/=(const modular_fixed_base &otr){
        int a = otr.data, m = _mod, u = 0, v = 1;
        if(a < _INV.size()) return *this *= _INV[a];
        while(a){
            int t = m / a;
            m -= t * a; swap(a, m);
            u -= t * v; swap(u, v);
        }
        assert(m == 1);
        return *this *= u;
    }
    uint data;
};
template<uint _mod> vector<modular_fixed_base<_mod>> modular_fixed_base<_mod>::_INV;
template<uint _mod> modular_fixed_base<_mod> modular_fixed_base<_mod>::_primitive_root;
template<uint _mod> bool operator==(const modular_fixed_base<_mod> &lhs, const modular_fixed_base<_mod> &rhs){ return lhs.data == rhs.data; }
template<uint _mod, class T, typename enable_if<is_integral<T>::value>::type* = nullptr> bool operator==(const modular_fixed_base<_mod> &lhs, T rhs){ return lhs == modular_fixed_base<_mod>(rhs); }
template<uint _mod, class T, typename enable_if<is_integral<T>::value>::type* = nullptr> bool operator==(T lhs, const modular_fixed_base<_mod> &rhs){ return modular_fixed_base<_mod>(lhs) == rhs; }
template<uint _mod> bool operator!=(const modular_fixed_base<_mod> &lhs, const modular_fixed_base<_mod> &rhs){ return !(lhs == rhs); }
template<uint _mod, class T, typename enable_if<is_integral<T>::value>::type* = nullptr> bool operator!=(const modular_fixed_base<_mod> &lhs, T rhs){ return !(lhs == rhs); }
template<uint _mod, class T, typename enable_if<is_integral<T>::value>::type* = nullptr> bool operator!=(T lhs, const modular_fixed_base<_mod> &rhs){ return !(lhs == rhs); }
template<uint _mod> bool operator<(const modular_fixed_base<_mod> &lhs, const modular_fixed_base<_mod> &rhs){ return lhs.data < rhs.data; }
template<uint _mod> bool operator>(const modular_fixed_base<_mod> &lhs, const modular_fixed_base<_mod> &rhs){ return lhs.data > rhs.data; }
template<uint _mod> bool operator<=(const modular_fixed_base<_mod> &lhs, const modular_fixed_base<_mod> &rhs){ return lhs.data <= rhs.data; }
template<uint _mod> bool operator>=(const modular_fixed_base<_mod> &lhs, const modular_fixed_base<_mod> &rhs){ return lhs.data >= rhs.data; }
template<uint _mod> modular_fixed_base<_mod> operator+(const modular_fixed_base<_mod> &lhs, const modular_fixed_base<_mod> &rhs){ return modular_fixed_base<_mod>(lhs) += rhs; }
template<uint _mod, class T, typename enable_if<is_integral<T>::value>::type* = nullptr> modular_fixed_base<_mod> operator+(const modular_fixed_base<_mod> &lhs, T rhs){ return modular_fixed_base<_mod>(lhs) += rhs; }
template<uint _mod, class T, typename enable_if<is_integral<T>::value>::type* = nullptr> modular_fixed_base<_mod> operator+(T lhs, const modular_fixed_base<_mod> &rhs){ return modular_fixed_base<_mod>(lhs) += rhs; }
template<uint _mod> modular_fixed_base<_mod> operator-(const modular_fixed_base<_mod> &lhs, const modular_fixed_base<_mod> &rhs){ return modular_fixed_base<_mod>(lhs) -= rhs; }
template<uint _mod, class T, typename enable_if<is_integral<T>::value>::type* = nullptr> modular_fixed_base<_mod> operator-(const modular_fixed_base<_mod> &lhs, T rhs){ return modular_fixed_base<_mod>(lhs) -= rhs; }
template<uint _mod, class T, typename enable_if<is_integral<T>::value>::type* = nullptr> modular_fixed_base<_mod> operator-(T lhs, const modular_fixed_base<_mod> &rhs){ return modular_fixed_base<_mod>(lhs) -= rhs; }
template<uint _mod> modular_fixed_base<_mod> operator*(const modular_fixed_base<_mod> &lhs, const modular_fixed_base<_mod> &rhs){ return modular_fixed_base<_mod>(lhs) *= rhs; }
template<uint _mod, class T, typename enable_if<is_integral<T>::value>::type* = nullptr> modular_fixed_base<_mod> operator*(const modular_fixed_base<_mod> &lhs, T rhs){ return modular_fixed_base<_mod>(lhs) *= rhs; }
template<uint _mod, class T, typename enable_if<is_integral<T>::value>::type* = nullptr> modular_fixed_base<_mod> operator*(T lhs, const modular_fixed_base<_mod> &rhs){ return modular_fixed_base<_mod>(lhs) *= rhs; }
template<uint _mod> modular_fixed_base<_mod> operator/(const modular_fixed_base<_mod> &lhs, const modular_fixed_base<_mod> &rhs) { return modular_fixed_base<_mod>(lhs) /= rhs; }
template<uint _mod, class T, typename enable_if<is_integral<T>::value>::type* = nullptr> modular_fixed_base<_mod> operator/(const modular_fixed_base<_mod> &lhs, T rhs) { return modular_fixed_base<_mod>(lhs) /= rhs; }
template<uint _mod, class T, typename enable_if<is_integral<T>::value>::type* = nullptr> modular_fixed_base<_mod> operator/(T lhs, const modular_fixed_base<_mod> &rhs) { return modular_fixed_base<_mod>(lhs) /= rhs; }
template<uint _mod> istream &operator>>(istream &in, modular_fixed_base<_mod> &number){
    long long x;
    in >> x;
    number.data = modular_fixed_base<_mod>::normalize(x);
    return in;
}
// #define _PRINT_AS_FRACTION
template<uint _mod> ostream &operator<<(ostream &out, const modular_fixed_base<_mod> &number){
#ifdef LOCAL
#ifdef _PRINT_AS_FRACTION
    out << number();
    cerr << "(";
    for(auto d = 1; ; ++ d){
        if((number * d).data <= 1000000){
            cerr << (number * d).data << "/" << d;
            break;
        }
        else if((-number * d).data <= 1000000){
            cerr << "-" << (-number * d).data << "/" << d;
            break;
        }
    }
    cerr << ")";
    return out;
#else
    return out << number();
#endif
#else
    return out << number();
#endif
}
#undef _PRINT_AS_FRACTION

const uint mod = 1e9 + 7; // 1000000007
// const uint mod = (119 << 23) + 1; // 998244353
// const uint mod = 1e9 + 9; // 1000000009
using Z = modular_fixed_base<mod>;

int n, L, a[105];
Z dp[105][105][5][1005];

#define FOR(i, a, b) for(int i = a; i < b; ++i)

void solve() {
    cin >> n >> L;
    for (int i = 1; i <= n; ++i)
        cin >> a[i];
    if (n == 1) {
        cout << 1 << endl;
        return;
    }
    sort(a + 1, a + n + 1);
    dp[0][0][0][0] = 1;
    FOR(i, 0, n) FOR(cc, 0, n) FOR(nend, 0, 3) FOR(sum, 0, L + 1) {
        Z val = dp[i][cc][nend][sum];
        int nsum = sum + (a[i + 1] - a[i]) * (2 * cc - nend);
        if (nsum < sum || nsum > L) continue;

        // case 1: new cc
        dp[i + 1][cc + 1][nend][nsum] += val * (cc + 1 - nend);

        // case 2: append to cc
        dp[i + 1][cc][nend][nsum] += val * (2 * cc - nend);

        // case 3: merge 2 cc
        if (cc) dp[i + 1][cc - 1][nend][nsum] += val * (cc - 1);

        // case 4: new end
        dp[i + 1][cc + 1][nend + 1][nsum] += val * (2 - nend);

        // case 5: append to make end
        dp[i + 1][cc][nend + 1][nsum] += val * (2 - nend);
        // cout << dp[i + 1][cc][nend + 1][nsum] << endl;
    }
    cout << accumulate(dp[n][1][2], dp[n][1][2] + L + 1, Z(0)) << endl;
}

signed main() {

#ifndef CDuongg
    if(fopen(taskname".inp", "r"))
        assert(freopen(taskname".inp", "r", stdin)), assert(freopen(taskname".out", "w", stdout));
#else
    freopen("bai3.inp", "r", stdin);
    freopen("bai3.out", "w", stdout);
    auto start = chrono::high_resolution_clock::now();
#endif

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    int t = 1; //cin >> t;
    while(t--) solve();

#ifdef CDuongg
   auto end = chrono::high_resolution_clock::now();
   cout << "\n"; for(int i = 1; i <= 100; ++i) cout << '=';
   cout << "\nExecution time: " << chrono::duration_cast<chrono::milliseconds> (end - start).count() << "[ms]" << endl;
#endif

}

Compilation message

skyscraper.cpp: In instantiation of 'static uint modular_fixed_base<_mod>::normalize(const T&) [with T = int; typename std::enable_if<std::is_integral<T>::value>::type* <anonymous> = 0; unsigned int _mod = 1000000007; uint = unsigned int]':
skyscraper.cpp:70:131:   required from 'modular_fixed_base<_mod>::modular_fixed_base(const T&) [with T = int; typename std::enable_if<std::is_integral<T>::value>::type* <anonymous> = 0; unsigned int _mod = 1000000007]'
skyscraper.cpp:192:22:   required from here
skyscraper.cpp:73:24: warning: comparison of integer expressions of different signedness: 'unsigned int' and 'int' [-Wsign-compare]
   73 |         uint v =  _mod <= sign * x ? sign * x % _mod : sign * x;
      |                   ~~~~~^~~~~~~~~~~
# Verdict Execution time Memory Grader output
1 Correct 1 ms 348 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 1 ms 604 KB Output is correct
4 Correct 1 ms 860 KB Output is correct
5 Correct 2 ms 1372 KB Output is correct
6 Correct 2 ms 1384 KB Output is correct
7 Correct 1 ms 1236 KB Output is correct
8 Correct 1 ms 1372 KB Output is correct
9 Correct 2 ms 1372 KB Output is correct
10 Correct 1 ms 1372 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 2 ms 2908 KB Output is correct
2 Correct 2 ms 2652 KB Output is correct
3 Correct 2 ms 3676 KB Output is correct
4 Correct 2 ms 2652 KB Output is correct
5 Correct 2 ms 2904 KB Output is correct
6 Correct 2 ms 3160 KB Output is correct
7 Correct 1 ms 2652 KB Output is correct
8 Correct 2 ms 3420 KB Output is correct
9 Correct 2 ms 3672 KB Output is correct
10 Correct 2 ms 2648 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 1 ms 348 KB Output is correct
2 Correct 0 ms 348 KB Output is correct
3 Correct 1 ms 604 KB Output is correct
4 Correct 1 ms 860 KB Output is correct
5 Correct 2 ms 1372 KB Output is correct
6 Correct 2 ms 1384 KB Output is correct
7 Correct 1 ms 1236 KB Output is correct
8 Correct 1 ms 1372 KB Output is correct
9 Correct 2 ms 1372 KB Output is correct
10 Correct 1 ms 1372 KB Output is correct
11 Correct 2 ms 2908 KB Output is correct
12 Correct 2 ms 2652 KB Output is correct
13 Correct 2 ms 3676 KB Output is correct
14 Correct 2 ms 2652 KB Output is correct
15 Correct 2 ms 2904 KB Output is correct
16 Correct 2 ms 3160 KB Output is correct
17 Correct 1 ms 2652 KB Output is correct
18 Correct 2 ms 3420 KB Output is correct
19 Correct 2 ms 3672 KB Output is correct
20 Correct 2 ms 2648 KB Output is correct
21 Correct 8 ms 14172 KB Output is correct
22 Correct 148 ms 115024 KB Output is correct
23 Correct 156 ms 122456 KB Output is correct
24 Correct 156 ms 143880 KB Output is correct
25 Correct 167 ms 126152 KB Output is correct
26 Correct 147 ms 125532 KB Output is correct
27 Correct 103 ms 165460 KB Output is correct
28 Correct 128 ms 167740 KB Output is correct
29 Correct 158 ms 166244 KB Output is correct
30 Correct 162 ms 125008 KB Output is correct