#include <bits/stdc++.h> typedef long long LLONG; typedef std::pair<int, int> PII; const int N = 1e5 + 10; struct Seg { int x, y, xx, yy, idx; void assign(int x1, int y1, int xx1, int yy1, int idx1) { x = x1; y = y1; xx = xx1; yy = yy1; idx = idx1; } } sgx[N], sgy[N]; int answer[N]; int fbit[N]; int sbit[N]; inline int lowBit(int k) { return k & -k; } inline void update(int bit[], int p, int v) { for(; p < N; p += lowBit(p)) { bit[p] += v; } } inline int query(int bit[], int p) { int rlt = 0; for(; p > 0; p -= lowBit(p)) { rlt += bit[p]; } return rlt; } inline void solveX(int topx, int topy) { std::sort(sgy, sgy + topy, [](Seg const & a, Seg const & b) { return a.x < b.x; }); std::sort(sgx, sgx + topx, [](Seg const & a, Seg const & b) { return a.x < b.x; }); memset(fbit, 0, sizeof(fbit)); memset(sbit, 0, sizeof(sbit)); for(int i = 0, j = 0; i < topx; ++i) { auto& v = sgx[i]; for(; j < topy && sgy[j].x < v.x; ++j) { update(fbit, sgy[j].y, 1); update(sbit, sgy[j].yy, 1); } answer[v.idx] = -(j - (query(fbit, N - 10) - query(fbit, v.y)) - query(sbit, v.y - 1)); } memset(fbit, 0, sizeof(fbit)); memset(sbit, 0, sizeof(sbit)); std::sort(sgx, sgx + topx, [](Seg const & a, Seg const & b) { return a.xx < b.xx; }); for(int i = 0, j = 0; i < topx; ++i) { auto& v = sgx[i]; for(; j < topy && sgy[j].x <= v.xx; ++j) { update(fbit, sgy[j].y, 1); update(sbit, sgy[j].yy, 1); } answer[v.idx] += (j - (query(fbit, N - 10) - query(fbit, v.y)) - query(sbit, v.y - 1)); } } inline void solveY(int topx, int topy) { std::sort(sgy, sgy + topy, [](Seg const & a, Seg const & b) { return a.y < b.y; }); std::sort(sgx, sgx + topx, [](Seg const & a, Seg const & b) { return a.y < b.y; }); memset(fbit, 0, sizeof(fbit)); memset(sbit, 0, sizeof(sbit)); for(int i = 0, j = 0; i < topy; ++i) { auto& v = sgy[i]; for(; j < topx && sgx[j].y < v.y; ++j) { update(fbit, sgx[j].x, 1); update(sbit, sgx[j].xx, 1); } answer[v.idx] = -(j - (query(fbit, N - 10) - query(fbit, v.x)) - query(sbit, v.x - 1)); } memset(fbit, 0, sizeof(fbit)); memset(sbit, 0, sizeof(sbit)); std::sort(sgy, sgy + topy, [](Seg const & a, Seg const & b) { return a.yy < b.yy; }); for(int i = 0, j = 0; i < topy; ++i) { auto& v = sgy[i]; for(; j < topx && sgx[j].y <= sgy[i].yy; ++j) { update(fbit, sgx[j].x, 1); update(sbit, sgx[j].xx, 1); } answer[v.idx] += (j - (query(fbit, N - 10) - query(fbit, v.x)) - query(sbit, v.x - 1)); } } std::map<PII, int>hs; inline void remove(int topx, int topy) { for(int i = 0; i < topx; ++i) { auto& v = sgx[i]; hs[ {v.x, v.y}] = v.idx; hs[ {v.xx, v.yy}] = v.idx; } for(int i = 0; i < topy; ++i) { auto& v = sgy[i]; PII p = {v.x, v.y}; if(hs.find(p) != hs.end()) { --answer[v.idx]; --answer[hs[p]]; } p = {v.xx, v.yy}; if(hs.find(p) != hs.end()) { --answer[v.idx]; --answer[hs[p]]; } } } int main() { int t; for(t = 1; t--;) { int n; scanf("%d", &n); int topx = 0, topy = 0; for(int i = 0; i < n; ++i) { int x, y, xx, yy; scanf("%d%d%d%d", &x, &y, &xx, &yy); if(x == xx) { if(y > yy) { std::swap(y, yy); } sgy[topy++].assign(x, y, xx, yy, i); } else { if(x > xx) { std::swap(x, xx); } sgx[topx++].assign(x, y, xx, yy, i); } } solveX(topx, topy); solveY(topx, topy); remove(topx, topy); LLONG sm = 0; for(int i = 0; i < topx; ++i) { sm += answer[sgx[i].idx]; } printf("%lld\n", sm); for(int i = 0; i < n; ++i) { printf("%d ", answer[i]); } } return 0; }
|