题目链接:点击打开链接
题意:
T个case
n个操作
1、 (x,y,z) 在三维平面的点上增加1
2、询问区间范围内的权值和。
思路:
cdq分治套cdq分治,然后套树状数组即可。。
#include <stdio.h> #include <iostream> #include <algorithm> #include <sstream> #include <stdlib.h> #include <string.h> #include <limits.h> #include <vector> #include <string> #include <time.h> #include <math.h> #include <iomanip> #include <queue> #include <stack> #include <set> #include <map> const int inf = 1e8; const double eps = 1e-8; const double pi = acos(-1.0); template <class T> inline bool rd(T &ret) { char c; int sgn; if (c = getchar(), c == EOF) return 0; while (c != '-' && (c<'0' || c>'9')) c = getchar(); sgn = (c == '-') ? -1 : 1; ret = (c == '-') ? 0 : (c - '0'); while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0'); ret *= sgn; return 1; } template <class T> inline void pt(T x) { if (x <0) { putchar('-'); x = -x; } if (x>9) pt(x / 10); putchar(x % 10 + '0'); } using namespace std; const int N = 50010 << 3; int maxn, c[N]; int lowbit(int x){ return x&-x; } void add(int x,int val){ while (x <= maxn)c[x] += val, x += lowbit(x); } int sum(int x){ int ans = 0; while (x)ans += c[x], x -= lowbit(x); return ans; } typedef long long ll; typedef pair<int, int> pii; class Node{ public: int op, x, y, z, id, add, ans; Node(){} Node(int _op, int _x, int _y, int _z, int _id, int _add) : op(_op), x(_x), y(_y), z(_z), id(_id), add(_add), ans(0){} }; int ans[N]; bool cmp(const Node &e1, const Node & e2) { if (e1.x == e2.x)return e1.id < e2.id; return e1.x < e2.x; } bool cmp2(const Node &e1, const Node & e2) { if (e1.y == e2.y)return e1.id < e2.id; return e1.y < e2.y; } Node q[N], t[N], v[N]; int n, top, tt; void cal(int l, int r){ //x有序 if (l == r)return; int mid = (l + r) >> 1; tt = 1; for (int i = l; i <= mid; i++)if (t[i].op == 1)v[++tt] = t[i]; for (int i = mid + 1; i <= r; i++)if(t[i].op == 2)v[++tt] = t[i]; sort(v + 1, v + tt + 1, cmp2); for (int i = 1; i <= tt; i++) if (v[i].op == 1) add(v[i].z, 1); else ans[v[i].id] += sum(v[i].z) * v[i].add; for (int i = 1; i <= tt; i++)if (v[i].op == 1)add(v[i].z, -1); cal(l, mid); cal(mid + 1, r); } void solve(int l, int r){ if (l == r)return; int mid = (l + r) >> 1; top = 1; for (int i = l; i <= mid; i++)if (q[i].op == 1)t[++top] = q[i]; for (int i = mid + 1; i <= r; i++)if (q[i].op == 2) t[++top] = q[i]; sort(t + 1, t + top + 1, cmp); cal(1, top); solve(l, mid); solve(mid + 1, r); } vector<int>G; int main(){ int T; rd(T); while (T-- > 0){ rd(n); G.clear(); int siz = 0; for (int i = 1, op, x1, x2, y1, y2, z1, z2; i <= n; i++) { rd(op); if (op == 1) { q[++siz].op = 1; ans[i] = -1; rd(q[siz].x); rd(q[siz].y); rd(q[siz].z); G.push_back(q[siz].z); } else { rd(x1); rd(y1); rd(z1); rd(x2); rd(y2); rd(z2); G.push_back(z2); G.push_back(z1); G.push_back(z1 - 1); ans[i] = 0; q[++siz] = Node(2, x2, y2, z2, i, 1); q[++siz] = Node(2, x1 - 1, y2, z2, i, -1); q[++siz] = Node(2, x2, y1 - 1, z2, i, -1); q[++siz] = Node(2, x1 - 1, y1 - 1, z2, i, 1); q[++siz] = Node(2, x2, y2, z1 - 1, i, -1); q[++siz] = Node(2, x1 - 1, y2, z1 - 1, i, 1); q[++siz] = Node(2, x2, y1 - 1, z1 - 1, i, 1); q[++siz] = Node(2, x1 - 1, y1 - 1, z1 - 1, i, -1); } } sort(G.begin(), G.end()); G.erase(unique(G.begin(), G.end()), G.end()); maxn = G.size(); for (int i = 1; i <= siz; i++)q[i].z = lower_bound(G.begin(), G.end(), q[i].z) - G.begin() + 1; solve(1, siz); for (int i = 1; i <= n; i++)if (ans[i] >= 0)pt(ans[i]), putchar('\n'); } return 0; }
时间: 2024-10-03 18:10:14