QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#552332#9242. An Easy Geometry Problemucup-team1198#WA 19ms21288kbC++207.4kb2024-09-07 22:05:472024-09-07 22:05:47

Judging History

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

  • [2024-09-07 22:05:47]
  • 评测
  • 测评结果:WA
  • 用时:19ms
  • 内存:21288kb
  • [2024-09-07 22:05:47]
  • 提交

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'