QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#552332 | #9242. An Easy Geometry Problem | ucup-team1198# | WA | 19ms | 21288kb | C++20 | 7.4kb | 2024-09-07 22:05:47 | 2024-09-07 22:05:47 |
Judging History
answer
#include <map>
#include <set>
#include <array>
#include <cmath>
#include <deque>
#include <bitset>
#include <random>
#include <string>
#include <vector>
#include <cassert>
#include <complex>
#include <iomanip>
#include <iostream>
#include <algorithm>
#include <unordered_map>
#include <unordered_set>
using namespace std;
const int MOD1 = 1'000'000'579;
const int MOD2 = 1'000'000'711;
const int MAXN = 400200;
const int BASE = 30011;
int BASEPOW1[MAXN];
int BASEPOW2[MAXN];
// tree1: add on subsegment, get in point
int mod[(1 << 19) + 228];
void build(int v, int left, int right, vector<int>& A) {
mod[v] = 0;
if (left + 1 == right) {
mod[v] = A[left];
return;
}
int mid = (left + right) / 2;
build(2 * v + 1, left, mid, A);
build(2 * v + 2, mid, right, A);
}
int get(int v, int left, int right, int i) {
if (left + 1 == right)
return mod[v];
int mid = (left + right) / 2;
if (i < mid)
return get(2 * v + 1, left, mid, i) + mod[v];
return get(2 * v + 2, mid, right, i) + mod[v];
}
void add(int v, int left, int right, int x, int y, int d) {
if (y <= left || right <= x)
return;
if (x <= left && right <= y) {
mod[v] += d;
return;
}
int mid = (left + right) / 2;
add(2 * v + 1, left, mid, x, y, d);
add(2 * v + 2, mid, right, x, y, d);
}
struct Hash {
int len;
int val1;
int val2;
Hash(): len(0), val1(0), val2(0) {}
Hash(int x): len(1), val1(x), val2(x) {
if (val1 < 0)
val1 += MOD1;
if (val2 < 0)
val2 += MOD2;
}
void add(int x) {
val1 += x;
if (val1 < 0)
val1 += MOD1;
if (val1 >= MOD1)
val1 -= MOD1;
val2 += x;
if (val2 < 0)
val2 += MOD2;
if (val2 >= MOD2)
val2 -= MOD2;
}
Hash(int len, int val1, int val2): len(len), val1(val1), val2(val2) {}
};
Hash combine(const Hash& left, const Hash& right) {
return Hash(left.len + right.len, (left.val1 * 1ll * BASEPOW1[right.len] + right.val1) % MOD1,
(left.val2 * 1ll * BASEPOW2[right.len] + right.val2) % MOD2);
}
Hash hashes[(1 << 20) + 228];
void build_hashes(int v, int left, int right, vector<int>& C) {
if (left + 1 == right) {
hashes[v] = Hash(C[left]);
return;
}
int mid = (left + right) / 2;
build_hashes(2 * v + 1, left, mid, C);
build_hashes(2 * v + 2, mid, right, C);
hashes[v] = combine(hashes[2 * v + 1], hashes[2 * v + 2]);
}
void add_hash(int v, int left, int right, int i, int x) {
if (left + 1 == right) {
hashes[v].add(x);
return;
}
int mid = (left + right) / 2;
if (i < mid)
add_hash(2 * v + 1, left, mid, i, x);
else
add_hash(2 * v + 2, mid, right, i, x);
hashes[v] = combine(hashes[2 * v + 1], hashes[2 * v + 2]);
}
Hash get_hash(int v, int left, int right, int x, int y) {
if (y <= left || right <= x)
return Hash();
if (x <= left && right <= y)
return hashes[v];
int mid = (left + right) / 2;
return combine(get_hash(2 * v + 1, left, mid, x, y), get_hash(2 * v + 2, mid, right, x, y));
}
bool operator==(const Hash& h1, const Hash& h2) {
return h1.len == h2.len && h1.val1 == h2.val1 && h1.val2 == h2.val2;
}
vector<int> solve(vector<int> A, vector<pair<pair<int, int>, int>> queries, int k, int b) {
int n = A.size();
int q = queries.size();
b *= 2;
for (int i = 0; i < n; ++i) {
A[i] = 2 * A[i] - i * k;
}
build(0, 0, n, A);
vector<int> C(2 * n);
for (int i = 0; i < n; ++i) {
C[i] = A[i] - (i == 0 ? 0 : A[i - 1]);
C[2 * n - i - 1] = -C[i];
}
build_hashes(0, 0, 2 * n, C);
auto get_r = [&](int i) {
if (i == 0 || i == n - 1)
return 0;
int prev = get(0, 0, n, i - 1), nxt = get(0, 0, n, i + 1);
if (nxt - prev != b)
return 0;
int left = 1, right = min(i + 1, n - i);
while (right - left > 1) {
int mid = (left + right) / 2;
auto h1 = get_hash(0, 0, 2 * n, i + 2, i + mid + 1);
auto h2 = get_hash(0, 0, 2 * n, 2 * n - i, 2 * n - i + mid - 1);
if (h1 == h2)
left = mid;
else
right = mid;
}
return left;
};
vector<int> ans;
for (auto [lr, v] : queries) {
auto [l, r] = lr;
if (r == l - 1) {
int i = l;
ans.emplace_back(get_r(i));
} else {
v *= 2;
add(0, 0, n, l, r + 1, v);
add_hash(0, 0, 2 * n, l, v);
add_hash(0, 0, 2 * n, 2 * n - l - 1, -v);
if (r + 1 < n) {
add_hash(0, 0, 2 * n, r + 1, -v);
add_hash(0, 0, 2 * n, 2 * n - r - 1, v);
}
}
}
return ans;
}
vector<int> dumb(vector<int> A, vector<pair<pair<int, int>, int>> queries, int k, int b) {
int n = A.size();
vector<int> ans;
for (auto [lr, v] : queries) {
auto [l, r] = lr;
if (r == l - 1) {
int i = l;
int r = 0;
while (i >= r + 1 && i + r + 1 < n && A[i + r + 1] - A[i - r - 1] == (r + 1) * k + b)
++r;
ans.emplace_back(r);
} else {
for (int i = l; i <= r; ++i)
A[i] += v;
}
}
return ans;
}
//#define STRESS
bool is_prime(int p) {
int i = 2;
while (i * i <= p) {
if (p % i == 0)
return false;
++i;
}
return true;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
BASEPOW1[0] = 1;
for (int i = 1; i < MAXN; ++i)
BASEPOW1[i] = BASEPOW1[i - 1] * 1ll * BASE % MOD1;
BASEPOW2[0] = 1;
for (int i = 1; i < MAXN; ++i)
BASEPOW2[i] = BASEPOW2[i - 1] * 1ll * BASE % MOD2;
#ifdef STRESS
auto rand_x = []() {
return rand() % 11 - 5;
};
for (int _ = 0; _ < 100100; ++_) {
int n = rand() % 30 + 1;
int q = rand() % 30 + 1;
int k = rand_x();
int b = rand_x();
vector<int> A(n);
for (int i = 0; i < n; ++i)
A[i] = rand_x();
vector<pair<pair<int, int>, int>> queries(q);
for (int i = 0; i < q; ++i) {
if (rand() % 2) {
int j = rand() % n;
queries[i] = make_pair(make_pair(j, j - 1), 0);
} else {
int l = rand() % n;
int r = rand() % (n - l) + l;
int x = rand_x();
queries[i] = make_pair(make_pair(l, r), x);
}
}
auto ans1 = solve(A, queries, k, b);
auto ans2 = solve(A, queries, k, b);
if (ans1 != ans2) {
cerr << "BUG!!!\n";
cerr << n << ' ' << q << ' ' << k << ' ' << b << '\n';
for (int x : A)
cerr << x << ' ';
cerr << '\n';
for (auto [lr, x] : queries) {
auto [l, r] = lr;
if (r == l - 1)
cerr << 2 << ' ' << r << '\n';
else
cerr << 1 << ' ' << l + 1 << ' ' << r + 1 << ' ' << x << '\n';
}
cerr << "wrong: ";
for (int x : ans1)
cerr << x << ' ';
cerr << "\nright: ";
for (int x : ans2)
cerr << x << ' ';
cerr << "\n\n\n";
}
}
#else
int n, q, k, b;
cin >> n >> q >> k >> b;
vector<int> A(n);
for (int i = 0; i < n; ++i)
cin >> A[i];
vector<pair<pair<int, int>, int>> queries(q);
for (int i = 0; i < q; ++i) {
int t;
cin >> t;
if (t == 1) {
int l, r, v;
cin >> l >> r >> v;
--l;
--r;
queries[i] = make_pair(make_pair(l, r), v);
} else {
int j;
cin >> j;
--j;
queries[i] = make_pair(make_pair(j, j - 1), 0);
}
}
auto ans = solve(A, queries, k, b);
for (int x : ans)
cout << x << '\n';
#endif
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 0ms
memory: 21288kb
input:
6 6 6 2 1 5 9 10 15 18 2 2 1 3 3 -3 2 2 1 3 4 3 2 3 2 4
output:
1 0 2 0
result:
ok 4 number(s): "1 0 2 0"
Test #2:
score: -100
Wrong Answer
time: 19ms
memory: 21264kb
input:
5000 5000 2 0 -329 -328 -327 -326 -325 -324 -323 -322 -321 -320 -319 -318 -317 -316 -315 -314 -313 -312 -311 -310 -309 -308 -307 -306 -305 -304 -303 -302 -301 -300 -299 -298 -297 -296 -295 -294 -293 -292 -291 -290 -289 -288 -287 -286 -285 -284 -283 -282 -281 -280 -279 -278 -277 -276 -275 -274 -273 -...
output:
2 304 73 29 61 292 139 48 116 99 6 5 53 93 3 91 65 29 33 306 21 24 17 21 281 12 16 1 33 7 18 96 7 40 39 13 7 47 43 77 1 87 33 16 22 5 6 189 53 1 35 107 43 34 3 79 20 21 44 91 96 36 2 27 23 30 32 19 40 138 27 37 12 58 15 72 154 142 171 57 22 7 33 15 24 155 68 25 70 14 10 4 10 2 34 39 207 33 164 11 19...
result:
wrong answer 9th numbers differ - expected: '17', found: '116'