题目链接:http://codeforces.com/gym/101964/problem/B
题意:q 种操作,①在(x,y)处加一个点,②加一个矩阵{(x1,y1),(x2,y2)},问每次操作后点在矩阵中或矩阵边界上的对数有多少。
题解:裸的CDQ分治,考虑对点和矩阵分别进行CDQ分治,因为x,y <= 1e9,要将其中一个坐标离散化。要注意先加点和先加矩阵的两种情况下,矩阵的差分边界是不同的。
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define ll long long 4 #define ull unsigned long long 5 #define mst(a,b) memset((a),(b),sizeof(a)) 6 #define mp(a,b) make_pair(a,b) 7 #define pi acos(-1) 8 #define pii pair<int,int> 9 #define pb push_back 10 const int INF = 0x3f3f3f3f; 11 const double eps = 1e-6; 12 const int MAXN = 1e5 + 10; 13 const int MAXM = 1e8 + 10; 14 const ll mod = 1e9 + 7; 15 16 struct node { 17 int op, x1, y1, x2, y2, id; 18 bool operator < (const node &rhs) { 19 if(x1 != rhs.x1) 20 return x1 < rhs.x1; 21 return id < rhs.id; 22 } 23 } a[MAXN], b[MAXN << 2], c[MAXN << 2]; 24 25 int tot; 26 27 void addnode(int op, int x1, int y1, int id) { 28 ++tot; 29 b[tot].op = op, b[tot].x1 = x1, b[tot].y1 = y1, b[tot].id = id; 30 } 31 32 int y[MAXN << 1], ysz = 0; 33 ll ans[MAXN]; 34 35 int lowbit(int x) { 36 return x & (-x); 37 } 38 39 ll bit[MAXN << 1]; 40 41 void add(int y, int val) { 42 while(y <= ysz) { 43 bit[y] += val; 44 y += lowbit(y); 45 } 46 } 47 48 ll query(int y) { 49 ll sum = 0; 50 while(y) { 51 sum += bit[y]; 52 y -= lowbit(y); 53 } 54 return sum; 55 } 56 57 void cdq(int l, int r) { 58 if(l == r) 59 return ; 60 int mid = (l + r) >> 1; 61 cdq(l, mid); 62 cdq(mid + 1, r); 63 int len = 0; 64 for(int i = l; i <= mid; i++) 65 if(b[i].id == 0) 66 c[++len] = b[i]; 67 for(int i = mid + 1; i <= r; i++) 68 if(b[i].id) 69 c[++len] = b[i]; 70 if(len == 0 || c[1].id || c[len].id == 0) 71 return ; 72 sort(c + 1, c + 1 + len); 73 for(int i = 1; i <= len; i++) { 74 if(c[i].id == 0) 75 add(c[i].y1, c[i].op); 76 else 77 ans[c[i].id] += 1ll * c[i].op * query(c[i].y1); 78 } 79 for(int i = 1; i <= len; i++) 80 if(c[i].id == 0) 81 add(c[i].y1, -c[i].op); 82 } 83 84 int main() { 85 #ifdef local 86 freopen("data.txt", "r", stdin); 87 // freopen("data.txt", "w", stdout); 88 #endif 89 mst(ans, 0); 90 int q; 91 scanf("%d", &q); 92 for(int i = 1; i <= q; i++) { 93 scanf("%d%d%d", &a[i].op, &a[i].x1, &a[i].y1); 94 y[++ysz] = a[i].y1; 95 if(a[i].op == 2) { 96 scanf("%d%d", &a[i].x2, &a[i].y2); 97 y[++ysz] = a[i].y2; 98 } 99 } 100 sort(y + 1, y + 1 + ysz); 101 ysz = unique(y + 1, y + 1 + ysz) - y - 1; 102 for(int i = 1; i <= q; i++) { 103 a[i].y1 = lower_bound(y + 1, y + 1 + ysz, a[i].y1) - y; 104 if(a[i].op == 2) 105 a[i].y2 = lower_bound(y + 1, y + 1 + ysz, a[i].y2) - y; 106 } 107 tot = 0; 108 for(int i = 1; i <= q; i++) { 109 if(a[i].op == 1) { 110 addnode(1, a[i].x1, a[i].y1, 0); 111 } else { 112 addnode(1, a[i].x1 - 1, a[i].y1 - 1, i); 113 addnode(-1, a[i].x2, a[i].y1 - 1, i); 114 addnode(-1, a[i].x1 - 1, a[i].y2, i); 115 addnode(1, a[i].x2, a[i].y2, i); 116 } 117 } 118 cdq(1, tot); 119 tot = 0; 120 for(int i = 1; i <= q; i++) { 121 if(a[i].op == 1) { 122 addnode(1, a[i].x1, a[i].y1, i); 123 } else { 124 addnode(1, a[i].x1, a[i].y1, 0); 125 addnode(-1, a[i].x2 + 1, a[i].y1, 0); 126 addnode(-1, a[i].x1, a[i].y2 + 1, 0); 127 addnode(1, a[i].x2 + 1, a[i].y2 + 1, 0); 128 } 129 } 130 cdq(1, tot); 131 for(int i = 1; i <= q; i++) { 132 ans[i] += ans[i - 1]; 133 printf("%lld ", ans[i]); 134 } 135 return 0; 136 }