Submission #722733

#TimeUsernameProblemLanguageResultExecution timeMemory
722733finn__Street Lamps (APIO19_street_lamps)C++17
100 / 100
2358 ms98496 KiB
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops") #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,avx2") #include <bits/stdc++.h> using namespace std; template <typename T, size_t N, size_t M> struct FenwickTree { unsigned a[N + 1], d[M]; vector<unsigned> c[N]; T t[M]; bool active = 0; void initialize() { size_t m = 0; active = 1; for (size_t i = 0; i < N; i++) { a[i] = m; sort(c[i].begin(), c[i].end()); c[i].resize(unique(c[i].begin(), c[i].end()) - c[i].begin()); copy(c[i].begin(), c[i].end(), d + a[i]); m += c[i].size(); } a[N] = m; } void increment(int64_t i, int64_t j, T x) { ++i, ++j; if (active) { while (i <= N) { int64_t k = upper_bound(d + a[i - 1], d + a[i], j) - (d + a[i - 1]); while (k <= a[i] - a[i - 1]) { t[a[i - 1] + k - 1] += x; k += k & -k; } i += i & -i; } } else { while (i <= N) c[i - 1].push_back(j), i += i & -i; } } T pointQuery(int64_t i, int64_t j) // it's really prefix sum { ++i, ++j; T x = 0; while (i) { int64_t k = upper_bound(d + a[i - 1], d + a[i], j) - (d + a[i - 1]); while (k) { x += t[a[i - 1] + k - 1]; k -= k & -k; } i -= i & -i; } return x; } void rangeIncrement(int64_t i, int64_t j, int64_t k, int64_t l, T x) { increment(i, j, x); increment(k + 1, j, -x); increment(i, l + 1, -x); increment(k + 1, l + 1, x); } }; template <size_t N> struct OrSegmentTree { bitset<1 << (32 - __builtin_clz(N))> t; bool operator[](size_t i) { return t[N + i]; } void reset() { t.reset(); } void set(size_t i, bool x) { t[i += N] = x; while (i >>= 1) t[i] = t[2 * i] | t[2 * i + 1]; } ptrdiff_t previousNonzero(size_t i) { i += N; do { if ((i & 1) && t[i - 1]) { --i; while (i < N) i = 2 * i + t[2 * i + 1]; return i - N; } } while ((i >>= 1) > 1); return -1; } ptrdiff_t nextNonzero(size_t i) { i += N; do { if (!(i & 1) && t[i + 1]) { ++i; while (i < N) i = 2 * i + !t[2 * i]; return i - N; } } while ((i >>= 1) > 1); return N; } }; constexpr size_t N = 300002; FenwickTree<int, N, 3725000> tree; OrSegmentTree<1 << 19> tree2; // set is too slow int queries[N][2]; int main() { ios_base::sync_with_stdio(0); cin.tie(0); size_t n, q; string s; cin >> n >> q >> s; for (size_t i = 0; i < n; i++) if (s[i] == '0') tree2.set(i, 1); for (size_t i = 0; i < q; i++) { string r; cin >> r; if (r == "query") { cin >> queries[i][0] >> queries[i][1]; --queries[i][0], --queries[i][1]; } else { cin >> queries[i][1], --queries[i][1]; queries[i][0] = -1; if (!tree2[queries[i][1]]) { tree.rangeIncrement(tree2.previousNonzero(queries[i][1]) + 1, queries[i][1] + 1, queries[i][1], min<size_t>(tree2.nextNonzero(queries[i][1]), n), 0); tree2.set(queries[i][1], 1); } else { tree2.set(queries[i][1], 0); tree.rangeIncrement(tree2.previousNonzero(queries[i][1]) + 1, queries[i][1] + 1, queries[i][1], min<size_t>(tree2.nextNonzero(queries[i][1]), n), 0); } } } tree2.reset(); for (size_t i = 0; i < n; i++) if (s[i] == '0') tree2.set(i, 1); tree.initialize(); for (int i = 0; i < q; i++) { if (queries[i][0] == -1) { if (!tree2[queries[i][1]]) { tree.rangeIncrement(tree2.previousNonzero(queries[i][1]) + 1, queries[i][1] + 1, queries[i][1], min<size_t>(tree2.nextNonzero(queries[i][1]), n), i + 1); tree2.set(queries[i][1], 1); } else { tree2.set(queries[i][1], 0); tree.rangeIncrement(tree2.previousNonzero(queries[i][1]) + 1, queries[i][1] + 1, queries[i][1], min<size_t>(tree2.nextNonzero(queries[i][1]), n), -(i + 1)); } } else { bool somethingInRange = tree2.nextNonzero(queries[i][0]) < queries[i][1] || tree2.previousNonzero(queries[i][1]) >= queries[i][0]; cout << tree.pointQuery(queries[i][0], queries[i][1]) + (somethingInRange ? 0 : (i + 1)) << '\n'; } } }

Compilation message (stderr)

street_lamps.cpp: In function 'int main()':
street_lamps.cpp:181:23: warning: comparison of integer expressions of different signedness: 'int' and 'size_t' {aka 'long unsigned int'} [-Wsign-compare]
  181 |     for (int i = 0; i < q; i++)
      |                     ~~^~~
street_lamps.cpp: In instantiation of 'void FenwickTree<T, N, M>::increment(int64_t, int64_t, T) [with T = int; long unsigned int N = 300002; long unsigned int M = 3725000; int64_t = long int]':
street_lamps.cpp:72:9:   required from 'void FenwickTree<T, N, M>::rangeIncrement(int64_t, int64_t, int64_t, int64_t, T) [with T = int; long unsigned int N = 300002; long unsigned int M = 3725000; int64_t = long int]'
street_lamps.cpp:162:88:   required from here
street_lamps.cpp:35:22: warning: comparison of integer expressions of different signedness: 'int64_t' {aka 'long int'} and 'long unsigned int' [-Wsign-compare]
   35 |             while (i <= N)
      |                    ~~^~~~
street_lamps.cpp:48:22: warning: comparison of integer expressions of different signedness: 'int64_t' {aka 'long int'} and 'long unsigned int' [-Wsign-compare]
   48 |             while (i <= N)
      |                    ~~^~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...