QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#870636#8618. Have You Seen This Subarray?ucup-team4435#RE 0ms3584kbC++207.8kb2025-01-25 17:08:352025-01-25 17:08:35

Judging History

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

  • [2025-01-25 17:08:35]
  • 评测
  • 测评结果:RE
  • 用时:0ms
  • 内存:3584kb
  • [2025-01-25 17:08:35]
  • 提交

answer

#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ld = long double;

#define all(a) begin(a), end(a)
#define len(a) int((a).size())

template<int SZ>
struct hash_t {
    inline static bool initialized = false;
    inline static int MOD[SZ], BASE[SZ];
    inline static std::vector<int> POWER[SZ];

    static void initialize() {
        assert(!initialized);
        initialized = true;
        std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());
        for (int i = 0; i < SZ; i++) {
            auto is_prime = [&](int x) {
                for (int i = 2; i * i <= x; i++)
                    if (x % i == 0)
                        return false;

                return true;
            };

            MOD[i] = int(8e5) + rng() % int(2e8 + 228);
            while (!is_prime(MOD[i]))
                MOD[i]++;

            BASE[i] = rng() % MOD[i];
            if (!(BASE[i] & 1))
                BASE[i]++;

            POWER[i].push_back(1);
        }
    }

    static void ensure(int n) {
        assert(initialized);
        if (int(POWER[0].size()) >= n)
            return;

        for (int i = 0; i < SZ; i++)
            for (int j = POWER[i].size(); j < n; j++)
                POWER[i].push_back(int64_t(POWER[i].back()) * BASE[i] % MOD[i]);
    }

    int length;
    std::array<int, SZ> h;

    hash_t() : length(0) {
        h.fill(0);
        if (!initialized)
            initialize();
    }

    template<typename T>
    hash_t(const T &value, int length = 1) : length(length) {
        if (!initialized)
            initialize();

        ensure(length);
        h.fill(0);
        for (int i = 0; i < SZ; i++)
            for (int j = 0; j < length; j++) {
                h[i] += int64_t(value + 1) * POWER[i][j] % MOD[i];
                if (h[i] >= MOD[i])
                    h[i] -= MOD[i];
            }
    }

    hash_t<SZ>& operator+=(const hash_t<SZ> &x) {
        assert(initialized);
        ensure(x.length + 1);
        for (int i = 0; i < SZ; i++)
            h[i] = (int64_t(h[i]) * POWER[i][x.length] + x.h[i]) % MOD[i];

        length += x.length;
        return *this;
    }

    hash_t<SZ>& operator-=(const hash_t<SZ> &x) {
        assert(initialized);
        assert(x.length <= length);
        ensure(length - x.length + 1);
        for (int i = 0; i < SZ; i++) {
            h[i] -= int64_t(x.h[i]) * POWER[i][length - x.length] % MOD[i];
            if (h[i] < 0)
                h[i] += MOD[i];
        }
        length -= x.length;
        return *this;
    }

    bool operator==(const hash_t<SZ> &x) const {
        if (length != x.length)
            return false;

        return h == x.h;
    }

    bool operator<(const hash_t<SZ> &x) const {
        if (length != x.length)
            return length < x.length;

        return h < x.h;
    }

    friend hash_t<SZ> operator+(const hash_t<SZ> &left, const hash_t<SZ> &right) {
        return hash_t<SZ>(left) += right;
    }

    friend hash_t<SZ> operator-(const hash_t<SZ> &left, const hash_t<SZ> &right) {
        return hash_t<SZ>(left) -= right;
    }
};

int main() {
    cin.tie(nullptr)->sync_with_stdio(false);

    int n, m, q;
    cin >> n >> m >> q;

    auto solve_big = [&]() {
        map<pair<int, int>, vector<pair<int, int>>> segs;
        map<pair<int, int>, int> last;

        auto finish = [&](pair<int, int> p, int i) {
            auto it = last.find(p);
            assert(it != last.end());
            segs[p].emplace_back(it->second, i);
            last.erase(it);
        };

        auto start = [&](pair<int, int> p, int i) {
            last[p] = i;
        };

        vector<int> a(n);
        iota(all(a), 0);
        for (int i = 0; i < n - 1; i++) {
            start({a[i], a[i + 1]}, -1);
        }

        for (int i = 0; i < m; i++) {
            int x, y;
            cin >> x >> y;
            x--, y--;
            assert(x < y);

            vector<int> to_update;
            if (x > 0) {
                to_update.push_back(x - 1);
            }
            to_update.push_back(x);
            if (x + 1 < y) {
                to_update.push_back(y - 1);
            }
            if (y + 1 < n) {
                to_update.push_back(y);
            }

            for (auto pos : to_update) {
                finish({a[pos], a[pos + 1]}, i);
            }
            swap(a[x], a[y]);
            for (auto pos : to_update) {
                start({a[pos], a[pos + 1]}, i);
            }
        }

        for (auto [p, when] : last) {
            segs[p].emplace_back(when, q);
        }

        // {
        //     int mx = 0;
        //     for (auto [_, v] : segs) {
        //         mx = max(mx, len(v));
        //     }
        //     cerr << "max size =" << mx << endl;
        // }

        while (q--) {
            int k;
            cin >> k;
            vector<int> b(k);
            for (auto &x : b) {
                cin >> x;
                x--;
            }
            if (k == 1) {
                cout << "0\n";
                continue;
            }

            vector<pair<int, int>> events;
            for (int i = 0; i + 1 < k; i++) {
                auto it = segs.find({b[i], b[i + 1]});
                if (it == segs.end()) {
                    continue;
                }
                for (auto [l, r] : it->second) {
                    events.emplace_back(l, 1);
                    events.emplace_back(r, -1);
                }
            }

            sort(all(events));
            int ans = -2, bal = 0;
            for (auto [t, delta] : events) {
                bal += delta;
                assert(bal >= 0);
                if (bal == k - 1) {
                    ans = t;
                    break;
                }
            }
            assert(ans != -2);
            cout << ans + 1 << '\n';
        }
    };

    auto solve_small = [&]() {
        using Hash = hash_t<1>;
        vector<pair<int, int>> swaps(m);
        for (auto &[x, y] : swaps) {
            cin >> x >> y;
            x--, y--;
        }

        vector<int> ans(q, -2);
        map<Hash, vector<int>> queries;
        for (int i = 0; i < q; i++) {
            int k;
            cin >> k;
            Hash cur(0, 0);
            while (k--) {
                int x;
                cin >> x;
                x--;
                cur += Hash(x);
            }
            queries[cur].push_back(i);
        }

        auto update = [&](Hash cur, int t) {
            auto it = queries.find(cur);
            if (it != queries.end()) {
                for (auto i : it->second) {
                    ans[i] = t;
                }
                queries.erase(it);
            }
        };

        vector<int> a(n);
        iota(all(a), 0);
        for (int i = 0; i < n; i++) {
            Hash cur(0, 0);
            for (int j = i; j < n; j++) {
                cur += Hash(a[j]);
                update(cur, -1);
            }
        }

        for (int t = 0; t < m; t++) {
            auto [x, y] = swaps[t];
            swap(a[x], a[y]);
            for (int pos : {x, y}) {
                for (int i = 0; i <= pos; i++) {
                    Hash cur(0, 0);
                    for (int j = i; j < n; j++) {
                        cur += Hash(a[j]);
                        if (j >= pos) {
                            update(cur, t);
                        }
                    }
                }
            }
        }

        for (auto x : ans) {
            assert(x != -2);
            cout << x + 1 << '\n';
        }
    };

    if (n <= 30) {
        solve_small();
    } else {
        solve_big();
    }
}

詳細信息

Test #1:

score: 100
Accepted
time: 0ms
memory: 3584kb

input:

6 3 5
1 5
3 4
1 6
2 4 1
3 3 1 5
3 3 4 5
4 5 2 4 3
2 6 2

output:

1
3
0
2
3

result:

ok 5 number(s): "1 3 0 2 3"

Test #2:

score: -100
Runtime Error

input:

50 50 16
21 30
14 39
5 32
31 48
38 50
40 49
14 33
32 42
7 15
5 25
24 28
8 10
18 24
5 39
4 37
9 28
29 39
2 35
11 32
48 49
12 17
38 44
26 33
12 40
19 49
40 41
17 18
20 30
11 15
21 36
37 38
7 48
17 21
8 38
30 34
3 31
7 12
31 47
2 37
20 41
13 40
33 39
10 49
19 40
12 30
23 28
9 45
27 32
4 37
27 29
2 44 4...

output:


result: