Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long llint;
- typedef pair <int, int> pii;
- #define TRACE(x) cerr << #x << ' ' << x << endl
- #define FOR(i, a, b) for (int i = (a); i < (b); i++)
- #define REP(i, n) FOR(i, 0, n)
- #define _ << ' ' <<
- #define X first
- #define Y second
- const int MAXN = 100100;
- const int offset = (1 << 18);
- struct node {
- int x, y, val, prop;
- int last_val;
- int set;
- node(){
- last_val = 1;
- prop = set = 0;
- val = 0;
- }
- };
- struct tournament {
- node p[offset * 2];
- node merge(node a, node b, int last) {
- node ret;
- ret.last_val = last;
- if (!b.set) ret = a;
- if (!a.set) ret = b;
- if (!b.set || !a.set) ret.last_val = last;
- if (!b.set || !a.set) return ret;
- ret.set = 1;
- ret.x = min(a.x, b.x);
- ret.y = max(a.y, b.y);
- ret.val = last * (b.x - a.y - 1) + a.val + b.val;
- return ret;
- }
- void postavi(int x, int real_x) {
- x += offset;
- p[x].x = p[x].y = real_x;
- p[x].set = 1;
- p[x].val = p[x].last_val = 1;
- x /= 2;
- while (x) {
- p[x] = merge(p[x * 2], p[x * 2 + 1], p[x].last_val);
- x /= 2;
- }
- }
- void send_prop(int x) {
- if (!p[x].prop) return;
- FOR(i, x * 2, x * 2 + 2) {
- p[i].val = p[i].y - p[i].x + 1 - p[i].val;
- p[i].prop ^= 1;
- p[i].last_val ^= 1;
- }
- p[x].prop = 0;
- }
- void update(int cvor, int l, int r, int a, int b) {
- if (l > b || r < a) return;
- if (l >= a && r <= b) {
- p[cvor].val = p[cvor].y - p[cvor].x + 1 - p[cvor].val;
- p[cvor].prop ^= 1;
- p[cvor].last_val ^= 1;
- return;
- }
- send_prop(cvor);
- int mid = (l + r) / 2;
- update(cvor * 2, l, mid, a, b);
- update(cvor * 2 + 1, mid + 1, r, a, b);
- p[cvor] = merge(p[cvor * 2], p[cvor * 2 + 1], p[cvor].last_val);
- }
- int get() {
- return p[1].val;
- }
- void print() {
- FOR(i, 1, 2 * offset) TRACE(p[i].last_val _ p[i].val _ p[i].prop _ p[i].x _ p[i].y _ p[i].set);
- }
- }T;
- int m, n, k;
- int a, b, c, d;
- vector <int> v;
- vector <pair <pii, pii> > ev;
- int get(int t) {
- return (int)(lower_bound(v.begin(), v.end(), t) - v.begin());
- }
- int main() {
- scanf("%d %d %d",&n,&m,&k);
- REP(i, k) {
- scanf("%d %d %d %d",&a,&b,&c,&d);
- v.push_back(c);
- v.push_back(d);
- ev.push_back({{a, -1}, {c, d}});
- ev.push_back({{b, 1}, {c, d}});
- }
- v.push_back(1);
- v.push_back(m);
- sort(v.begin(), v.end());
- sort(ev.begin(), ev.end());
- v.erase(unique(v.begin(), v.end()), v.end());
- REP(i, (int)v.size()) T.postavi(i, v[i]);
- int last = ev[0].X.X;
- llint sol = 0;
- REP(i, (int)ev.size()) {
- int x = ev[i].X.X;
- vector <pii> add, rem;
- for (int j = i; j < (int)ev.size() && ev[j].X.X == ev[i].X.X; j++) {
- if (ev[j].X.Y == -1) add.push_back({get(ev[j].Y.X), get(ev[j].Y.Y)});
- else rem.push_back({get(ev[j].Y.X), get(ev[j].Y.Y)});
- }
- int prije = T.get();
- sol += (llint)prije * (x - last);
- if (x == n && add.empty()) sol += prije;
- REP(j, (int)add.size()) T.update(1, 0, offset - 1, add[j].X, add[j].Y);
- last = x;
- if (!add.empty()) {
- last++;
- sol += T.get();
- }
- REP(j, (int)rem.size()) T.update(1, 0, offset - 1, rem[j].X, rem[j].Y);
- while (i < (int)ev.size() && ev[i].X.X == x) i++;
- i--;
- }
- printf("%lld\n", sol);
- return 0;
- }
Add Comment
Please, Sign In to add comment