题目描述:
平面上有一些鱼,初始时鱼会在一些位置,某些时刻编号在一段区间内的鱼会同时向x轴正方向,或y轴正方向平移一定距离,某些时刻会询问一个矩形内鱼的数量。
解题思路:
显然地,求一个矩形内的鱼可以用矩形四个顶点为右上角的整个左下矩形加加减减。那么问题就转化为一个顶点左下角矩形内鱼的数量。注意到鱼只会向右和向上的话,那就很好做。维护两颗线段树,分别维护编号在l~r的鱼的x坐标最大值、y坐标最大值。每次修改对应区间加。每次如果区间最大值大于限制,那就找出最大值的位置,赋为-inf,同时在树状数组删掉改点就可以了。询问就在树状数组上询问区间点的数量。
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 const int N = 3e4 + 10, inf = 1e9 + 1; 7 int T, n, m, x1, y1, x2, y2, fis[N][2], ans[N], sum[N]; 8 9 struct que{int s, l, r, d;} q[N]; 10 11 struct node{int mx, tag;} tx[N * 8], ty[N * 8]; 12 13 int lowbit(int x) {return x & -x;} 14 15 void add(int x, int v) { 16 while (x <= N - 10) sum[x] += v, x += lowbit(x); 17 } 18 19 int Sum(int x) { 20 int r = 0; 21 while (x) r += sum[x], x -= lowbit(x); 22 return r; 23 } 24 25 void buildx(int o, int l, int r) { 26 if (l == r) { 27 tx[o].mx = fis[l][0]; 28 tx[o].tag = 0; 29 return; 30 } 31 int m = l + r >> 1; 32 buildx(o << 1, l, m); 33 buildx(o << 1 | 1, m + 1, r); 34 tx[o].mx = max(tx[o << 1].mx, tx[o << 1 | 1].mx); 35 tx[o].tag = 0; 36 } 37 38 void buildy(int o, int l, int r) { 39 if (l == r) { 40 ty[o].mx = fis[l][1]; 41 ty[o].tag = 0; 42 return; 43 } 44 int m = l + r >> 1; 45 buildy(o << 1, l, m); 46 buildy(o << 1 | 1, m + 1, r); 47 ty[o].mx = max(ty[o << 1].mx, ty[o << 1 | 1].mx); 48 ty[o].tag = 0; 49 } 50 51 void pushdownx(int o) { 52 if (!tx[o].tag) return; 53 tx[o << 1].tag += tx[o].tag; 54 tx[o << 1 | 1].tag += tx[o].tag; 55 tx[o].mx += tx[o].tag; 56 tx[o].tag = 0; 57 } 58 59 void pushdowny(int o) { 60 if (!ty[o].tag) return; 61 ty[o << 1].tag += ty[o].tag; 62 ty[o << 1 | 1].tag += ty[o].tag; 63 ty[o].mx += ty[o].tag; 64 ty[o].tag = 0; 65 } 66 67 int queryx(int o, int l, int r) { 68 if (l == r) return l; 69 int m = l + r >> 1; 70 pushdownx(o << 1); 71 pushdownx(o << 1 | 1); 72 if (tx[o << 1].mx > tx[o << 1 | 1].mx) return queryx(o << 1, l, m); 73 return queryx(o << 1 | 1, m + 1, r); 74 } 75 76 int queryy(int o, int l, int r) { 77 if (l == r) return l; 78 int m = l + r >> 1; 79 pushdowny(o << 1); 80 pushdowny(o << 1 | 1); 81 if (ty[o << 1].mx > ty[o << 1 | 1].mx) return queryy(o << 1, l, m); 82 return queryy(o << 1 | 1, m + 1, r); 83 } 84 85 void changex(int o, int l, int r, int p, int v) { 86 pushdownx(o); 87 if (l == r) { 88 tx[o].mx = v; 89 return; 90 } 91 int m = l + r >> 1; 92 if (p <= m) changex(o << 1, l, m, p, v); 93 else changex(o << 1 | 1, m + 1, r, p, v); 94 tx[o].mx = max(tx[o << 1].mx, tx[o << 1 | 1].mx); 95 } 96 97 void changey(int o, int l, int r, int p, int v) { 98 pushdowny(o); 99 if (l == r) { 100 ty[o].mx = v; 101 return; 102 } 103 int m = l + r >> 1; 104 if (p <= m) changey(o << 1, l, m, p, v); 105 else changey(o << 1 | 1, m + 1, r, p, v); 106 ty[o].mx = max(ty[o << 1].mx, ty[o << 1 | 1].mx); 107 } 108 109 void updatax(int o, int l, int r) { 110 tx[o].mx = max(tx[o << 1].mx + tx[o << 1].tag, tx[o << 1 | 1].mx + tx[o << 1 | 1].tag); 111 } 112 113 void modifyx(int o, int l, int r, int x, int y, int d) { 114 if (x <= l && r <= y) { 115 tx[o].tag += d; 116 return; 117 } 118 pushdownx(o); 119 int m = l + r >> 1; 120 if (x <= m) modifyx(o << 1, l, m, x, y, d); 121 if (y > m) modifyx(o << 1 | 1, m + 1, r, x, y, d); 122 updatax(o, l, r); 123 } 124 125 void updatay(int o, int l, int r) { 126 ty[o].mx = max(ty[o << 1].mx + ty[o << 1].tag, ty[o << 1 | 1].mx + ty[o << 1 | 1].tag); 127 } 128 129 void modifyy(int o, int l, int r, int x, int y, int d) { 130 if (x <= l && r <= y) { 131 ty[o].tag += d; 132 return; 133 } 134 pushdowny(o); 135 int m = l + r >> 1; 136 if (x <= m) modifyy(o << 1, l, m, x, y, d); 137 if (y > m) modifyy(o << 1 | 1, m + 1, r, x, y, d); 138 updatay(o, l, r); 139 } 140 141 int work(int x, int y, int z) { 142 buildx(1, 1, n); 143 buildy(1, 1, n); 144 memset(sum, 0, sizeof sum); 145 for (int i = 1; i <= n; i ++) add(i, 1); 146 for (int i = 1; i <= m; i ++) { 147 while (tx[1].mx > x) { 148 int p = queryx(1, 1, n); 149 changex(1, 1, n, p, -inf); 150 if (Sum(p) - Sum(p - 1)) add(p, -1); 151 } 152 while (ty[1].mx > y) { 153 int p = queryy(1, 1, n); 154 changey(1, 1, n, p, -inf); 155 if (Sum(p) - Sum(p - 1)) add(p, -1); 156 } 157 if (q[i].s == 1) modifyx(1, 1, n, q[i].l, q[i].r, q[i].d); 158 if (q[i].s == 2) modifyy(1, 1, n, q[i].l, q[i].r, q[i].d); 159 if (q[i].s == 3) ans[i] += z * (Sum(q[i].r) - Sum(q[i].l - 1)); 160 } 161 } 162 163 int main() { 164 scanf("%d", &T); 165 while (T --) { 166 scanf("%d", &n); 167 scanf("%d %d %d %d", &x1, &y1, &x2, &y2); 168 for (int i = 1; i <= n; i ++) scanf("%d %d", &fis[i][0], &fis[i][1]); 169 scanf("%d", &m); 170 for (int i = 1; i <= m; i ++) { 171 scanf("%d %d %d", &q[i].s, &q[i].l, &q[i].r); 172 if (q[i].s != 3) scanf("%d", &q[i].d); 173 } 174 memset(ans, 0, sizeof ans); 175 work(x2, y2, 1), work(x1 - 1, y1 - 1, 1), work(x2, y1 - 1, -1), work(x1 - 1, y2, -1); 176 for (int i = 1; i <= m; i ++) if (q[i].s == 3) printf("%d\n", ans[i]); 177 } 178 return 0; 179 }
HDU #5283 Senior's Fish
时间: 2024-10-06 15:11:29