QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#870636 | #8618. Have You Seen This Subarray? | ucup-team4435# | RE | 0ms | 3584kb | C++20 | 7.8kb | 2025-01-25 17:08:35 | 2025-01-25 17:08:35 |
Judging History
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...