Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- using ll = long long;
- using pi = pair<int, int>;
- #define st first
- #define nd second
- const int INF = 1.5e9;
- struct Tree1D
- {
- int n;
- vector<int> c;
- vector<int> sum;
- Tree1D(): n(0), c({-INF, INF}), sum(0) {}
- void add_point(int x)
- {
- c.push_back(x);
- }
- void init()
- {
- sort(c.begin(), c.end());
- c.erase(unique(c.begin(), c.end()), c.end());
- n = 1;
- while(n<(int)c.size()) n*=2;
- sum.resize(2*n, 0);
- }
- int convert(int x)
- {
- return lower_bound(c.begin(), c.end(), x)-c.begin();
- }
- void add(int v, int x)
- {
- v = convert(v)+n;
- while(v)
- {
- sum[v] += x;
- v /= 2;
- }
- }
- int query(int va, int vb)
- {
- //cerr << va << " " << vb << "\n";
- va = convert(va)+n; vb = convert(vb+1)-1+n;
- //cerr << "Tree1D: " << va << " " << vb << ", " << c[va-n] <<" " << c[vb-n] << "\n";
- if(vb<va) return 0;
- int res = sum[va];
- if(va!=vb) res += sum[vb];
- while(va/2!=vb/2)
- {
- if(va%2==0) res += sum[va+1];
- if(vb%2==1) res += sum[vb-1];
- va /= 2;
- vb /= 2;
- }
- //cerr << "res=" << res << "\n";
- return res;
- }
- };
- struct Tree2D
- {
- int n;
- vector<int> c;
- vector<Tree1D> sum;
- Tree2D(): n(0), c({-INF, INF}), sum(0) {}
- void add_point(int x)
- {
- c.push_back(x);
- }
- void init()
- {
- sort(c.begin(), c.end());
- c.erase(unique(c.begin(), c.end()), c.end());
- n = 1;
- while(n<(int)c.size()) n*=2;
- sum.resize(2*n);
- }
- int convert(int x)
- {
- return lower_bound(c.begin(), c.end(), x)-c.begin();
- }
- void add_point2d(pi p)
- {
- int v = convert(p.st)+n;
- while(v)
- {
- sum[v].add_point(p.nd);
- v /= 2;
- }
- }
- void init2()
- {
- for(int i=1; i<2*n; ++i) sum[i].init();
- }
- void add(pi p, int x)
- {
- int v = convert(p.st)+n;
- while(v)
- {
- sum[v].add(p.nd, x);
- v /= 2;
- }
- }
- int query(pi p1, pi p2)
- {
- int va = convert(p1.st)+n;
- int vb = convert(p2.st+1)-1+n;
- //cerr << "Tree2d: " << va << " " << vb << ", " << c[va-n] << " " << c[vb-n] << "\n";
- if(vb<va) return 0;
- int res = sum[va].query(p1.nd, p2.nd);
- if(vb!=va) res += sum[vb].query(p1.nd, p2.nd);
- while(va/2!=vb/2)
- {
- if(va%2==0) res += sum[va+1].query(p1.nd, p2.nd);
- if(vb%2==1) res += sum[vb-1].query(p1.nd, p2.nd);
- va /=2; vb /= 2;
- }
- return res;
- }
- void startup(const vector<pi>& p)
- {
- for(pi i: p) add_point(i.st);
- init();
- for(pi i: p) add_point2d(i);
- init2();
- }
- };
- struct Tree1Drev
- {
- int n;
- vector<int> c;
- vector<int> sum;
- Tree1Drev(): n(0), c({-INF, INF}), sum(0) {}
- void add_point(int x)
- {
- c.push_back(x);
- }
- void init()
- {
- sort(c.begin(), c.end());
- c.erase(unique(c.begin(), c.end()), c.end());
- n = 1;
- while(n<(int)c.size()) n*=2;
- sum.resize(2*n, 0);
- }
- int convert(int x)
- {
- return lower_bound(c.begin(), c.end(), x)-c.begin();
- }
- int query(int v)
- {
- v = convert(v)+n;
- int res = 0;
- while(v)
- {
- res += sum[v];
- v /= 2;
- }
- return res;
- }
- void add(int va, int vb, int x)
- {
- //cerr << va << " " << vb << "\n";
- va = convert(va)+n; vb = convert(vb+1)-1+n;
- //cerr << "Tree1D: " << va << " " << vb << ", " << c[va-n] <<" " << c[vb-n] << "\n";
- if(vb<va) return;
- sum[va]+=x;
- if(va!=vb) sum[vb] += x;
- while(va/2!=vb/2)
- {
- if(va%2==0) sum[va+1]+=x;
- if(vb%2==1) sum[vb-1]+=x;
- va /= 2;
- vb /= 2;
- }
- //cerr << "res=" << res << "\n";
- }
- };
- struct Tree2Drev
- {
- int n;
- vector<int> c;
- vector<Tree1Drev> sum;
- Tree2Drev(): n(0), c({-INF, INF}), sum(0) {}
- void add_point(int x)
- {
- c.push_back(x);
- }
- void init()
- {
- sort(c.begin(), c.end());
- c.erase(unique(c.begin(), c.end()), c.end());
- n = 1;
- while(n<(int)c.size()) n*=2;
- sum.resize(2*n);
- }
- int convert(int x)
- {
- return lower_bound(c.begin(), c.end(), x)-c.begin();
- }
- void add_point2d(pi p)
- {
- int v = convert(p.st)+n;
- while(v)
- {
- sum[v].add_point(p.nd);
- v /= 2;
- }
- }
- void init2()
- {
- for(int i=1; i<2*n; ++i) sum[i].init();
- }
- int query(pi p)
- {
- int v = convert(p.st)+n;
- int res = 0;
- while(v)
- {
- res += sum[v].query(p.nd);
- v /= 2;
- }
- return res;
- }
- void add(pi p1, pi p2, int x)
- {
- int va = convert(p1.st)+n;
- int vb = convert(p2.st+1)-1+n;
- //cerr << "Tree2d: " << va << " " << vb << ", " << c[va-n] << " " << c[vb-n] << "\n";
- if(vb<va) return;
- sum[va].add(p1.nd, p2.nd, x);
- if(vb!=va) sum[vb].add(p1.nd, p2.nd, x);
- while(va/2!=vb/2)
- {
- if(va%2==0) sum[va+1].add(p1.nd, p2.nd, x);
- if(vb%2==1) sum[vb-1].add(p1.nd, p2.nd, x);
- va /=2; vb /= 2;
- }
- }
- void startup(const vector<pi>& p)
- {
- for(pi i: p) add_point(i.st);
- init();
- for(pi i: p) add_point2d(i);
- init2();
- }
- };
- const int N = 1e5+5;
- int type[N];
- pi q1[N], q2[N];
- int main()
- {
- int q;
- scanf("%d", &q);
- //q = 1e5;
- vector<pi> points;
- for(int i=0; i<q; ++i)
- {
- scanf("%d%d%d", &type[i], &q1[i].st, &q1[i].nd);
- if(type[i]==2) scanf("%d%d", &q2[i].st, &q2[i].nd);
- //type[i] = i%2+1;
- //q1[i].st = rand()%1000+1; q1[i].nd = rand()%1000+1;
- //q2[i] = pi(10000, 10000);
- if(type[i]==1) points.push_back(q1[i]);
- }
- Tree2D pt;
- Tree2Drev rt;
- pt.startup(points);
- rt.startup(points);
- ll res = 0;
- for(int i=0; i<q; ++i)
- {
- if(type[i]==1)
- {
- pt.add(q1[i], 1);
- res += rt.query(q1[i]);
- }
- else
- {
- rt.add(q1[i], q2[i], 1);
- res += pt.query(q1[i], q2[i]);
- }
- printf("%lld\n", res);
- }
- }
- /*
- 5
- 1 2 3
- 1 2 2
- 1 3 4
- 2 1 1 5 5
- 2 2 2 2 2
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement