QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#336753#8285. Shell Sortucup-team1191#TL 1295ms18100kbC++209.8kb2024-02-24 20:50:212024-02-24 20:50:22

Judging History

你现在查看的是最新测评结果

  • [2024-02-24 20:50:22]
  • 评测
  • 测评结果:TL
  • 用时:1295ms
  • 内存:18100kb
  • [2024-02-24 20:50:21]
  • 提交

answer

#include <bits/stdc++.h>
#define fr first
#define sc second
#define all(a) (a).begin(), (a).end()
#define unique(a) a.resize(unique(a.begin(), a.end()) - a.begin())

using namespace std;

#ifdef ONPC
mt19937 rnd(223);
#else
mt19937 rnd(chrono::high_resolution_clock::now()
			.time_since_epoch().count());
#endif

#define TIME (clock() * 1.0 / CLOCKS_PER_SEC)

using ll = long long;
using ld = double;

const int maxn = 1e5 + 100, inf = 1e9 + 100;

// если модуль подается на вход, убрать все <> и раскомментировать нужные строки
using uint = unsigned int;
using ull = unsigned long long;
template <uint MD> struct ModInt {
    using M = ModInt;
    // static int MD;
    uint v;
    ModInt(ll _v = 0) { set_v(uint(_v % MD + MD)); }
    M& set_v(uint _v) {
        v = (_v < MD) ? _v : _v - MD;
        return *this;
    }
    explicit operator bool() const { return v != 0; }
    M operator-() const { return M() - *this; }
    M operator+(const M& r) const { return M().set_v(v + r.v); }
    M operator-(const M& r) const { return M().set_v(v + MD - r.v); }
    M operator*(const M& r) const { return M().set_v(uint((ull)v * r.v % MD)); }
    M operator/(const M& r) const { return *this * r.inv(); }
    M& operator+=(const M& r) { return *this = *this + r; }
    M& operator-=(const M& r) { return *this = *this - r; }
    M& operator*=(const M& r) { return *this = *this * r; }
    M& operator/=(const M& r) { return *this = *this / r; }
    bool operator==(const M& r) const { return v == r.v; }
    bool operator!=(const M& r) const { return v != r.v; }
    M inv() const;
    friend istream& operator>>(istream& is, M& r) { ll x; is >> x; r = M(x); return is; }
    friend ostream& operator<<(ostream& os, const M& r) { return os << r.v; }
};

template<uint MD>
ModInt<MD> pow(ModInt<MD> x, ll n) {
    ModInt<MD> r = 1;
    while (n) {
        if (n & 1) r *= x;
        x *= x;
        n >>= 1;
    }
    return r;
}

template<uint MD>
ModInt<MD> ModInt<MD>::inv() const { return pow(*this, MD - 2); }
// or copy egcd and {return egcd(MD, v, 1).second;}

// if MD is from input
// this line is necessary, read later as you wish
// int ModInt::MD;

using Mint = ModInt<1'000'000'007>;
// using Mint = double;

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;

int cur_cnt;
gp_hash_table<int, int> masks;
vector<tuple<int, int, int>> in[32];

vector<int> p;

int calc(const vector<int>& d) {
    int ans = 0;
    for (int t : d) {
        for (int i = t; i < (int)p.size(); ++i) {
            int j = i;
            while (j >= t && p[j - t] > p[j]) {
                if (p[j] == 1) {
                    ++ans;
                }
                swap(p[j - t], p[j]);
                j -= t;
            }
        }
    }
    return ans;
}

void gen(int n, int mask, int t, const vector<int>& d) {
    int mid = cur_cnt++;
    masks[mask] = mid;
    if (mask == 0) {
        return;
    }
    for (int i = 0; i < n; i++) {
        if (((mask >> i) & 1) == 1 && (i < t || ((mask >> (i - t)) & 1) == 0)) {
            int new_mask = mask ^ (1 << i);
            for (int x = 0; x < n; x++) {
                if (x == i) {
                    p[x] = 1;
                } else {
                    if ((mask >> x) & 1) {
                        p[x] = 2;
                    } else {
                        p[x] = 0;
                    }
                }
            }
            int w = calc(d);
            if (masks.find(new_mask) == masks.end()) {
                gen(n, new_mask, t, d);
            }
            in[__builtin_popcount(mask)].emplace_back(mid, masks[new_mask], w);
        }
    }
}

pair<int, Mint> fast(int n, const vector<int>& d) {
    if (d.size() == 1) {
        return {n * (n - 1) / 2, Mint(1)};
    }
    p.resize(n);
    masks.clear();
    //masks.reserve(2e6);
    for (int i = 0; i <= n; i++) {
        in[i].clear();
    }
    cur_cnt = 0;
    int add = 0;
    for (int ost = 0; ost < d[0]; ost++) {
        int cnt = (n - ost + d[0] - 1) / d[0];
        add += cnt * (cnt - 1) / 2;
    }
    gen(n, (1 << n) - 1, d[0], d);
    vector<pair<int, Mint>> dp(masks.size(), make_pair(-1, 0));
    dp[masks[0]] = make_pair(add, 1);
    for (int sz = 1; sz <= n; sz++) {
        for (auto [from, to, w] : in[sz]) {
            auto pr = dp[to];
            pr.first += w;
            if (dp[from].first < pr.first) {
                dp[from].first = pr.first;
                dp[from].second = 0;
            }
            if (dp[from].first == pr.first) {
                dp[from].second += pr.second;
            }
        }
    }
    return dp[masks[(1 << n) - 1]];
}

int calc(vector<int> p, const vector<int>& d) {
    int ans = 0;
    for (int t : d) {
        for (int i = t; i < (int)p.size(); ++i) {
            int j = i;
            while (j >= t && p[j - t] > p[j]) {
                swap(p[j - t], p[j]);
                ++ans;
                j -= t;
            }
        }
    }
    return ans;
}

auto solve(int n, const vector<int>& d) {
    mt19937 rnd(239);
    int best = -1;
    set<vector<int>> best_p;
    int last_it = -1;
    vector<pair<int, int>> swaps;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < i; ++j) {
            swaps.emplace_back(j, i);
        }
    }
    for (int random_it = 0; random_it < last_it * 2 + 1000; random_it++) {
        vector<int> p(n);
        iota(p.begin(), p.end(), 0);
        shuffle(p.begin(), p.end(), rnd);
        int cur = calc(p, d);
        shuffle(all(swaps), rnd);
        int i_swaps = 0;
        int unchanged = 0;
        for (int inner_it = 0; inner_it < 10000 && unchanged <= swaps.size() * 2; inner_it++) {
            auto [i, j] = swaps[i_swaps];
            ++i_swaps;
            if (i_swaps == swaps.size()) {
                shuffle(all(swaps), rnd);
                i_swaps = 0;
            }
            swap(p[i], p[j]);
            int new_val = calc(p, d);
            unchanged++;
            if (new_val >= cur) {
                if (new_val > cur) {
                    unchanged--;
                }
                cur = new_val;
                if (best < cur) {
                    best_p.clear();
                    best = cur;
                }
                if (best == cur) {
                    if (best_p.insert(p).second) {
                        last_it = random_it;
                    }
                }
            } else {
                swap(p[i], p[j]);
            }
        }
    }
    return make_tuple(best, (int)best_p.size(), last_it);
}

vector<int> opt;
vector<vector<int>> opts;
int n;

void gen() {
    opts.emplace_back(opt.rbegin(), opt.rend());
    for (int k = opt.back() + 1; k < n && k <= 10; ++k) {
        opt.push_back(k);
        gen();
        opt.pop_back();
    }
}

void solve() {
    //*
    cin >> n;
    int m;
    cin >> m;
    vector<int> d(m);
    for (int i = 0; i < m; i++) {
        cin >> d[i];
    }
    auto [v1, v2] = fast(n, d);
    cout << v1 << " " << v2 << "\n";
    return;
    //*/


    n = 10;
    opt = {1};
    gen();

    vector<int> p(n);
    vector<int> v(n);
    int it = 0;
    for (const auto& d : opts) {
        ++it;
        cerr << it << "/" << opts.size() << endl;
//        iota(all(p), 1);
//        int max_ans = -1;
//        int cnt = 0;
//        vector<int> sample;
//        vector<set<vector<int>>> hists(d.size());
//        do {
//            for (int i = 0; i < n; ++i) {
//                v[i] = p[i];
//            }
//            int cur = 0;
//            int iit = 0;
//            vector<vector<int>> hist;
//            for (int t : d) {
//                hist.push_back(v);
//                for (int i = t; i < n; ++i) {
//                    int j = i;
//                    while (j >= t && v[j - t] > v[j]) {
//                        swap(v[j - t], v[j]);
//                        ++cur;
//                        j -= t;
//                    }
//                }
//                ++iit;
//            }
//            if (cur > max_ans) {
//                for (auto& v : hists)
//                    v.clear();
//                max_ans = cur;
//                sample = p;
//                cnt = 0;
//            }
//            if (cur == max_ans) {
//                for (int i = 0; i < hists.size(); ++i) {
//                    hists[i].insert(hist[i]);
//                }
//                ++cnt;
//            }
//        } while (next_permutation(all(p)));
//        cout << "ans=" << max_ans << "  \tcnt=" << cnt;
//        cout << "  \tpath =";
//        for (auto& v : hists)
//            cout << ' ' << v.size();
//        cout << ' ' << 1;
        cout << "  \tfor d =";
        for (int i : d)
            cout << ' ' << i;
//        cout << "  \tsample =";
//        for (int i : sample)
//            cout << ' ' << i;
        cout << "| ";
        auto [fast_ans, fast_cnt, fast_last_it] = solve(n, d);
//        if (make_pair(fast_ans, fast_cnt) != make_pair(max_ans, cnt)) {
//            cout << " HUY";
//        }
        auto [best_ans, best_cnt] = fast(n, d);
        assert(best_ans == fast_ans && best_cnt == fast_cnt);
        cout << " " << fast_ans << " " << fast_cnt << ' ' << fast_last_it;
        cout << "\n";
        cout << best_ans << " " << best_cnt << "\n";
        if (fast_last_it > 5000)
            cout << " !!!!!!!!!!!!!!!!!!!";
        cout << '\n';
    }
}

int main() {
#ifdef ONPC
    freopen("../a.in", "r", stdin);
    freopen("../a.out", "w", stdout);
#endif
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout << fixed;
    cout.precision(20);
    solve();
    cerr << "\n\nConsumed " << TIME << endl;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 100
Accepted
time: 1ms
memory: 3976kb

input:

2 2
2 1

output:

1 1

result:

ok 2 number(s): "1 1"

Test #2:

score: 0
Accepted
time: 0ms
memory: 3920kb

input:

5 4
5 4 2 1

output:

6 4

result:

ok 2 number(s): "6 4"

Test #3:

score: 0
Accepted
time: 1ms
memory: 3888kb

input:

8 4
6 3 2 1

output:

15 4

result:

ok 2 number(s): "15 4"

Test #4:

score: 0
Accepted
time: 1ms
memory: 4164kb

input:

8 6
8 7 5 4 2 1

output:

14 2

result:

ok 2 number(s): "14 2"

Test #5:

score: 0
Accepted
time: 1ms
memory: 4084kb

input:

8 3
8 7 1

output:

22 7

result:

ok 2 number(s): "22 7"

Test #6:

score: 0
Accepted
time: 0ms
memory: 3836kb

input:

8 1
1

output:

28 1

result:

ok 2 number(s): "28 1"

Test #7:

score: 0
Accepted
time: 2ms
memory: 4112kb

input:

16 2
6 1

output:

77 15

result:

ok 2 number(s): "77 15"

Test #8:

score: 0
Accepted
time: 13ms
memory: 5168kb

input:

16 8
10 9 8 7 6 5 4 1

output:

57 5

result:

ok 2 number(s): "57 5"

Test #9:

score: 0
Accepted
time: 21ms
memory: 5304kb

input:

16 10
10 9 8 7 6 5 4 3 2 1

output:

57 3

result:

ok 2 number(s): "57 3"

Test #10:

score: 0
Accepted
time: 14ms
memory: 5220kb

input:

16 7
10 9 8 6 5 4 1

output:

49 1

result:

ok 2 number(s): "49 1"

Test #11:

score: 0
Accepted
time: 5ms
memory: 4136kb

input:

16 4
7 6 2 1

output:

52 9

result:

ok 2 number(s): "52 9"

Test #12:

score: 0
Accepted
time: 6ms
memory: 4200kb

input:

22 3
5 3 1

output:

100 1

result:

ok 2 number(s): "100 1"

Test #13:

score: 0
Accepted
time: 0ms
memory: 4008kb

input:

22 1
1

output:

231 1

result:

ok 2 number(s): "231 1"

Test #14:

score: 0
Accepted
time: 908ms
memory: 18048kb

input:

22 4
10 8 3 1

output:

97 4

result:

ok 2 number(s): "97 4"

Test #15:

score: 0
Accepted
time: 1248ms
memory: 18064kb

input:

22 5
10 7 6 3 1

output:

92 70

result:

ok 2 number(s): "92 70"

Test #16:

score: 0
Accepted
time: 934ms
memory: 18100kb

input:

22 6
10 9 8 7 3 1

output:

97 1

result:

ok 2 number(s): "97 1"

Test #17:

score: 0
Accepted
time: 1295ms
memory: 18092kb

input:

22 10
10 9 8 7 6 5 4 3 2 1

output:

109 1

result:

ok 2 number(s): "109 1"

Test #18:

score: 0
Accepted
time: 5ms
memory: 4112kb

input:

14 2
10 1

output:

61 210

result:

ok 2 number(s): "61 210"

Test #19:

score: 0
Accepted
time: 1ms
memory: 3992kb

input:

18 2
2 1

output:

117 1

result:

ok 2 number(s): "117 1"

Test #20:

score: -100
Time Limit Exceeded

input:

30 2
9 1

output:


result: