QOJ.ac
QOJ
ID | Problem | Submitter | Result | Time | Memory | Language | File size | Submit time | Judge time |
---|---|---|---|---|---|---|---|---|---|
#106998 | #6409. Classical Data Structure Problem | hos_lyric | WA | 2ms | 3468kb | C++14 | 10.0kb | 2023-05-20 06:04:40 | 2023-05-20 06:04:43 |
Judging History
answer
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
// fast IO by yosupo
// sc.read(string &) appends the input
struct Scanner {
FILE* fp = nullptr;
char line[(1 << 15) + 1];
size_t st = 0, ed = 0;
void reread() {
memmove(line, line + st, ed - st);
ed -= st;
st = 0;
ed += fread(line + ed, 1, (1 << 15) - ed, fp);
line[ed] = '\0';
}
bool succ() {
while (true) {
if (st == ed) {
reread();
if (st == ed) return false;
}
while (st != ed && isspace(line[st])) st++;
if (st != ed) break;
}
if (ed - st <= 50) reread();
return true;
}
template <class T, enable_if_t<is_same<T, string>::value, int> = 0>
bool read_single(T& ref) {
if (!succ()) return false;
while (true) {
size_t sz = 0;
while (st + sz < ed && !isspace(line[st + sz])) sz++;
ref.append(line + st, sz);
st += sz;
if (!sz || st != ed) break;
reread();
}
return true;
}
template <class T, enable_if_t<is_integral<T>::value, int> = 0>
bool read_single(T& ref) {
if (!succ()) return false;
bool neg = false;
if (line[st] == '-') {
neg = true;
st++;
}
ref = T(0);
while (isdigit(line[st])) {
ref = 10 * ref + (line[st++] - '0');
}
if (neg) ref = -ref;
return true;
}
template <class T> bool read_single(vector<T>& ref) {
for (auto& d : ref) {
if (!read_single(d)) return false;
}
return true;
}
void read() {}
template <class H, class... T> void read(H& h, T&... t) {
bool f = read_single(h);
assert(f);
read(t...);
}
Scanner(FILE* _fp) : fp(_fp) {}
};
struct Printer {
public:
template <bool F = false> void write() {}
template <bool F = false, class H, class... T>
void write(const H& h, const T&... t) {
if (F) write_single(' ');
write_single(h);
write<true>(t...);
}
template <class... T> void writeln(const T&... t) {
write(t...);
write_single('\n');
}
Printer(FILE* _fp) : fp(_fp) {}
~Printer() { flush(); }
private:
static constexpr size_t SIZE = 1 << 15;
FILE* fp;
char line[SIZE], small[50];
size_t pos = 0;
void flush() {
fwrite(line, 1, pos, fp);
pos = 0;
}
void write_single(const char& val) {
if (pos == SIZE) flush();
line[pos++] = val;
}
template <class T, enable_if_t<is_integral<T>::value, int> = 0>
void write_single(T val) {
if (pos > (1 << 15) - 50) flush();
if (val == 0) {
write_single('0');
return;
}
if (val < 0) {
write_single('-');
val = -val; // todo min
}
size_t len = 0;
while (val) {
small[len++] = char('0' + (val % 10));
val /= 10;
}
for (size_t i = 0; i < len; i++) {
line[pos + i] = small[len - 1 - i];
}
pos += len;
}
void write_single(const string& s) {
for (char c : s) write_single(c);
}
void write_single(const char* s) {
size_t len = strlen(s);
for (size_t i = 0; i < len; i++) write_single(s[i]);
}
template <class T> void write_single(const vector<T>& val) {
auto n = val.size();
for (size_t i = 0; i < n; i++) {
if (i) write_single(' ');
write_single(val[i]);
}
}
void write_single(long double d){
{
long long v=d;
write_single(v);
d-=v;
}
write_single('.');
for(int _=0;_<8;_++){
d*=10;
long long v=d;
write_single(v);
d-=v;
}
}
};
Scanner sc(stdin);
Printer pr(stdout);
#ifndef LIBRA_DATA_STRUCTURE_AA_TREE_H_
#define LIBRA_DATA_STRUCTURE_AA_TREE_H_
#include <assert.h>
////////////////////////////////////////////////////////////////////////////////
// leaf node: uncut interval
// internal node: concatnation of intervals for l and r (constitutes AA tree)
// T: monoid representing information of an interval.
// T() should return the identity.
// T(S s) should represent a single element of the array.
// T::push(T &l, T &r) should push the lazy update.
// T::pull(const T &l, const T &r) should pull two intervals.
// T::sz should represent the length of the interval.
// T::init(SignedInteger sz_) should initialize an interval.
template <class T> struct AATree {
using X = decltype(T().sz);
AATree *l, *r;
int lev;
T t;
// Creates [0, sz).
AATree(X sz) : l(nullptr), r(nullptr), lev(0), t() {
t.init(sz);
}
inline X sz() {
return t.sz;
}
inline void push() {
t.push(l->t, r->t);
}
inline void pull() {
t.pull(l->t, r->t);
}
static void free(AATree *u) {
if (!u) return;
free(u->l);
free(u->r);
delete u;
}
// v---u v---u //
// / \ \ -> / / \ //
// o o o o o o //
static AATree *rotSkew(AATree *u) {
if (u->l == nullptr || u->lev != u->l->lev) return u;
AATree *v = u->l;
u->l = v->r;
u->pull();
v->r = u;
v->pull();
return v;
}
// v //
// / \ //
// u---v---o u o //
// / / -> / \ //
// o o o o //
static AATree *rotSplit(AATree *u) {
if (u->r == nullptr || u->lev != u->r->lev) return u;
if (u->r->r == nullptr || u->lev != u->r->r->lev) return u;
AATree *v = u->r;
u->r = v->l;
u->pull();
v->l = u;
++v->lev;
v->pull();
return v;
}
// Cuts at a.
static AATree *cut(AATree *u, X a) {
if (a <= 0 || u->sz() <= a) return u;
if (!u->lev) {
u->l = new AATree(a);
u->r = new AATree(u->sz() - a);
u->lev = 1;
u->push();
return u;
}
u->push();
if (a <= u->l->sz()) {
u->l = cut(u->l, a);
u->pull();
return rotSplit(rotSkew(u));
} else {
u->r = cut(u->r, a - u->l->sz());
u->pull();
return rotSplit(rotSkew(u));
}
}
// Applies T::f(args...) to [a, b).
template <class F, class... Args> void ch(X a, X b, F f, Args &&... args) {
if (b <= 0 || sz() <= a) return;
if (a <= 0 && sz() <= b) {
(t.*f)(args...);
return;
}
push();
l->ch(a, b, f, args...);
r->ch(a - l->sz(), b - l->sz(), f, args...);
pull();
}
// Calculates the product for [a, b).
T get(X a, X b) {
if (b <= 0 || sz() <= a) return T();
if (a <= 0 && sz() <= b) return t;
push();
const T prodL = l->get(a, b);
const T prodR = r->get(a - l->sz(), b - l->sz());
T prod;
prod.pull(prodL, prodR);
return prod;
}
// Calculates T::f(args...) of a monoid type for [a, b).
// op(-, -) should calculate the product.
// e() should return the identity.
template <class Op, class E, class F, class... Args>
#if __cplusplus >= 201402L
auto
#else
decltype((std::declval<T>().*F())())
#endif
get(int a, int b, Op op, E e, F f, Args &&... args) {
if (b <= 0 || sz() <= a) return e();
if (a <= 0 && sz() <= b) return (t.*f)(args...);
const auto prodL = l->get(a, b);
const auto prodR = r->get(a - l->sz(), b - l->sz());
return op(prodL, prodR);
}
// TODO: findRight, findLeft
};
////////////////////////////////////////////////////////////////////////////////
#endif // LIBRA_DATA_STRUCTURE_AA_TREE_H_
// range add, range sum
template <class X, class T> struct NodeSum {
X sz;
T sum, lz;
NodeSum() : sz(0), sum(0), lz(0) {}
void init(T sz_) {
sz = sz_;
}
void push(NodeSum &l, NodeSum &r) {
if (lz) {
l.add(lz);
r.add(lz);
lz = 0;
}
}
void pull(const NodeSum &l, const NodeSum &r) {
sz = l.sz + r.sz;
sum = l.sum + r.sum;
}
void add(const T &val) {
sum += sz * val;
lz += val;
}
T getSum() const {
return sum;
}
};
int main() {
int N, M;
sc.read(N, M);
const int mask = (1 << M) - 1;
unsigned x = 0;
using Node = NodeSum<int, unsigned>;
using AA = AATree<Node>;
auto seg = new AA(1 << M);
for (int i = 1; i <= N; ++i) {
int P, Q;
sc.read(P, Q);
int L = (P + x) & mask;
int R = (Q + x) & mask;
if (L > R) swap(L, R);
++R;
seg = AA::cut(seg, L);
seg = AA::cut(seg, R);
seg->ch(L, R, &Node::add, i);
x += seg->get(L, R).sum;
}
pr.writeln(x);
AA::free(seg);
return 0;
}
Details
Tip: Click on the bar to expand more detailed information
Test #1:
score: 100
Accepted
time: 2ms
memory: 3360kb
input:
5 2 2 1 1 3 3 2 1 0 0 2
output:
87
result:
ok 1 number(s): "87"
Test #2:
score: 0
Accepted
time: 2ms
memory: 3432kb
input:
1 1 1 1
output:
1
result:
ok 1 number(s): "1"
Test #3:
score: 0
Accepted
time: 2ms
memory: 3468kb
input:
1 2 3 1
output:
3
result:
ok 1 number(s): "3"
Test #4:
score: 0
Accepted
time: 0ms
memory: 3436kb
input:
1 5 31 15
output:
17
result:
ok 1 number(s): "17"
Test #5:
score: 0
Accepted
time: 2ms
memory: 3356kb
input:
1 20 366738 218765
output:
147974
result:
ok 1 number(s): "147974"
Test #6:
score: 0
Accepted
time: 2ms
memory: 3428kb
input:
1 30 86669484 41969116
output:
44700369
result:
ok 1 number(s): "44700369"
Test #7:
score: 0
Accepted
time: 2ms
memory: 3340kb
input:
10 5 20 31 2 2 14 18 13 25 26 4 22 9 15 9 19 16 15 27 9 20
output:
1414
result:
ok 1 number(s): "1414"
Test #8:
score: 0
Accepted
time: 2ms
memory: 3356kb
input:
100 10 245 987 817 813 743 560 548 504 116 479 223 199 775 998 126 542 791 823 96 318 69 349 0 584 245 601 119 513 93 820 115 307 838 978 249 767 433 287 240 8 22 683 169 720 395 592 903 866 919 652 510 563 858 345 938 250 550 239 981 7 784 926 212 644 272 365 490 871 470 987 571 53 65 593 515 370 1...
output:
20383734
result:
ok 1 number(s): "20383734"
Test #9:
score: 0
Accepted
time: 2ms
memory: 3468kb
input:
1000 1 0 1 1 0 1 0 1 0 1 0 0 1 0 0 0 1 0 0 0 0 1 1 0 0 1 0 0 1 0 1 1 1 0 1 0 1 0 0 1 1 1 0 0 1 1 1 0 0 0 1 0 0 1 1 1 0 1 1 1 1 0 0 1 1 1 0 0 0 0 1 1 1 0 1 0 0 1 1 1 1 0 1 0 0 0 1 0 1 1 1 1 0 1 0 1 1 1 1 1 0 1 1 1 0 1 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0 1 1 0 1 1 1 0 0 0 1 0 1 1 0 0 1 0 0 0 0 0 0 1 1 1 1 1...
output:
190098735
result:
ok 1 number(s): "190098735"
Test #10:
score: 0
Accepted
time: 2ms
memory: 3356kb
input:
1000 5 8 18 31 28 19 3 15 28 5 22 19 1 26 27 17 17 5 26 6 27 10 6 5 2 3 19 6 6 28 16 17 16 0 21 7 31 13 25 13 10 28 30 0 13 21 5 2 9 25 28 4 18 31 13 1 26 30 3 5 8 19 16 22 10 15 17 3 25 6 27 18 26 27 1 26 29 18 21 14 20 5 1 26 9 7 13 19 25 15 11 24 17 12 28 24 17 4 27 20 27 31 18 25 17 1 28 5 0 16 ...
output:
794181769
result:
ok 1 number(s): "794181769"
Test #11:
score: -100
Wrong Answer
time: 1ms
memory: 3464kb
input:
1000 10 732 399 190 578 491 867 330 55 113 400 34 734 790 927 201 156 107 359 790 398 401 523 634 505 570 305 281 513 551 35 610 33 231 330 833 756 213 444 412 315 139 165 533 21 35 977 319 884 894 72 149 667 16 538 282 860 850 550 100 99 801 138 159 34 468 852 840 853 368 994 469 906 393 298 464 89...
output:
3976408120
result:
wrong answer 1st numbers differ - expected: '755182648', found: '3976408120'