There is a grid of length and width \(50515093\) points. A clock is placed on
each grid point. The clocks are all analogue showing a single hour hand
initially pointing at \(12\).
The four numbers \(N_t = (S_{4t-4},
S_{4t-3}, S_{4t-2}, S_{4t-1})\) represent a range within the
grid, with the first pair of numbers representing the x-bounds and the
second pair representing the y-bounds. For example, if \(N_t = (3,9,47,20)\), the range would be
\(3\le x\le 9\) and \(20\le y\le47\), and would include \(196\) clocks.
For each \(t\)\((t>0)\), the clocks within the range
represented by \(N_t\) are moved to the
next hour \(12\rightarrow 1\rightarrow
2\rightarrow \cdots\).
We define \(C(t)\) to be the sum of
the hours that the clock hands are pointing to after timestep \(t\).
You are given \(C(0) =
30621295449583788\), \(C(1)
= 30613048345941659\), \(C(10) =
21808930308198471\) and \(C(100) =
16190667393984172\).
int MOD = 50515093; constint N = 100000; structRect { int x0, x1, y0, y1; };
structEvent { int l, r, delta; };
structSegTree { int n; vector<int> freq; vector<int> lazy;
SegTree() : n(0) {}
SegTree(const vector<int> &w) { n = (int)w.size(); freq.assign((4 * n + 5) * 12, 0); lazy.assign(4 * n + 5, 0); build(1, 0, n, w); }
inlinevoidrotate_node(int u, int sh) { sh %= 12; if (sh < 0) sh += 12; if (!sh) return; int tmp[12]; int *p = &freq[u * 12]; for (int i = 0; i < 12; i++) tmp[(i + sh) % 12] = p[i]; for (int i = 0; i < 12; i++) p[i] = tmp[i]; lazy[u] = (lazy[u] + sh) % 12; }
inlinevoidpush(int u) { if (!lazy[u]) return; int sh = lazy[u]; rotate_node(u << 1, sh); rotate_node(u << 1 | 1, sh); lazy[u] = 0; }
inlinevoidpull(int u) { int *p = &freq[u * 12]; int *L = &freq[(u << 1) * 12]; int *R = &freq[(u << 1 | 1) * 12]; for (int i = 0; i < 12; i++) p[i] = L[i] + R[i]; }
voidbuild(int u, int l, int r, const vector<int> &w) { if (l + 1 == r) { freq[u * 12 + 0] = (int)w[l]; return; } int m = (l + r) >> 1; build(u << 1, l, m, w); build(u << 1 | 1, m, r, w); pull(u); }
voidupdate(int ql, int qr, int delta) { update(1, 0, n, ql, qr, delta); }
voidupdate(int u, int l, int r, int ql, int qr, int delta) { if (qr <= l || r <= ql) return; if (ql <= l && r <= qr) { rotate_node(u, delta); return; } push(u); int m = (l + r) >> 1; update(u << 1, l, m, ql, qr, delta); update(u << 1 | 1, m, r, ql, qr, delta); pull(u); }
inline ll total()const { constint *p = &freq[1 * 12]; ll res = 12LL * p[0]; for (int i = 1; i < 12; i++) res += 1LL * i * p[i]; return res; } };
vector<int> w(nx - 1); for (int i = 0; i + 1 < nx; i++) w[i] = xs[i + 1] - xs[i];
SegTree seg(w);
vector<vector<Event>> events(ny); for (constauto &rc : rects) { int xl = lower_bound(xs.begin(), xs.end(), rc.x0) - xs.begin(); int xr = lower_bound(xs.begin(), xs.end(), rc.x1) - xs.begin(); int yl = lower_bound(ys.begin(), ys.end(), rc.y0) - ys.begin(); int yr = lower_bound(ys.begin(), ys.end(), rc.y1) - ys.begin(); events[yl].push_back({xl, xr, +1}); events[yr].push_back({xl, xr, -1}); }
ll ans = 0; int yPrev = 0; for (int i = 0; i < ny; i++) { int y = ys[i]; ll dy = (ll)y - yPrev; ans += dy * seg.total(); for (auto &ev : events[i]) seg.update(ev.l, ev.r, ev.delta); yPrev = y; } return ans; }