三维的cdq分治,需要cdq分治套cdq分治去降掉两维。c++一直超时,g++才能过也是醉了。
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdio>
#define CLR(a, b) memset(a, b, sizeof(a))
#define LL long long
using namespace std;
const int maxn = 50050;
int c[maxn * 2], ans[maxn];
struct query
{
int x, y, z, type, v, id, q;
query() {}
query(int x, int y, int z, int v, int type, int id, int q)
:x(x), y(y), z(z), v(v), type(type), id(id), q(q) {}
}Q[maxn*8];
int tmd;
inline int lowbit(int x)
{
return x & (-x);
}
inline void add(int x, int ad)
{
while(x <= tmd)
{
c[x] += ad;
x += lowbit(x);
}
}
inline int sum(int x)
{
int ret = 0;
while(x)
{
ret += c[x];
x -= lowbit(x);
}
return ret;
}
vector<int> vz;
inline bool cmpx(query a, query b)
{
return a.x < b.x || (a.x == b.x && a.id < b.id);
}
inline bool cmpy(query a, query b)
{
return a.y < b.y || (a.y == b.y && a.id < b.id);
}
query Q2[maxn*8], tmp1[maxn*8], tmp2[maxn*8];
void cdq2(int l, int r)
{
if(l >= r) return ;
int m = (l + r) >> 1;
cdq2(l, m); cdq2(m + 1, r);
int t1 = 0, t2 = 0;
for(int i = l; i <= m; i ++)
if(Q2[i].type&1) tmp1[t1 ++] = Q2[i];
for(int i = m + 1; i <= r; i ++)
if(Q2[i].type&2) tmp2[t2 ++] = Q2[i];
sort(tmp1, tmp1 + t1, cmpy);
sort(tmp2, tmp2 + t2, cmpy);
// sort(Q2 + l, Q2 + m + 1, cmpy);
// sort(Q2 + m + 1, Q2 + r + 1, cmpy);
int now = 0;
for(int i = 0; i < t2; i ++)
{
while(now < t1 && tmp1[now].y <= tmp2[i].y)
{
add(tmp1[now].z, 1);
now ++;
}
ans[tmp2[i].q] += tmp2[i].v * sum(tmp2[i].z);
}
for(int i = 0; i < now; i ++)
add(tmp1[i].z, -1);
}
void cdq(int l, int r)
{
if(l >= r) return ;
int m = (l + r) >> 1;
cdq(l, m); cdq(m + 1, r);
int tot = 0;
for(int i = l; i <= m; i ++)
if(Q[i].type&1) Q2[++ tot] = Q[i];
if(!tot) return ;
for(int i = m + 1; i <= r; i ++)
if(Q[i].type&2) Q2[++ tot] = Q[i];
sort(Q2 + 1, Q2 + tot + 1, cmpx);
cdq2(1, tot);
}
inline int input(int &x)
{
x = 0; char c = getchar();
while(c > '9' || c < '0') c = getchar();
while(c <= '9' && c >= '0')
{
x = (x << 1) + (x << 3) + c - '0';
c = getchar();
}
return x;
}
int main()
{
int n, T;
input(T);
// scanf("%d", &T);
// T = 2;
while(T --)
{
int tot = 0, q = 1;
input(n);
vz.clear();
for(int i = 1; i <= n; i ++)
{
int op;
op = input(op);
// scanf("%d", &op);
if(op == 1)
{
int x, y, z;
input(x), input(y), input(z);
// scanf("%d%d%d", &x, &y, &z);
tot ++;
Q[tot] = query(x, y, z, 1, 1, tot, 0);
vz.push_back(z);
}
else
{
int x1, x2, y1, y2, z1, z2;
input(x1); input(y1); input(z1);
input(x2); input(y2); input(z2);
// scanf("%d%d%d%d%d%d", &x1, &y1, &z1, &x2, &y2, &z2);
vz.push_back(z1 - 1);
vz.push_back(z2);
tot ++;
Q[tot] = query(x2, y2, z2, 1, 2, tot, q);
tot ++;
Q[tot] = query(x1 - 1, y2, z2, -1, 2, tot, q);
tot ++;
Q[tot] = query(x2, y1 - 1, z2, -1, 2, tot, q);
tot ++;
Q[tot] = query(x2, y2, z1 - 1, -1, 2, tot, q);
tot ++;
Q[tot] = query(x1 - 1, y1 - 1, z2, 1, 2, tot, q);
tot ++;
Q[tot] = query(x1 - 1, y2, z1 - 1, 1, 2, tot, q);
tot ++;
Q[tot] = query(x2, y1 - 1, z1 - 1, 1, 2, tot, q);
tot ++;
Q[tot] = query(x1 - 1, y1 - 1, z1 - 1, -1, 2, tot, q);
// ans[q] = 0;
q ++;
}
}
CLR(ans, 0); CLR(c, 0);
sort(vz.begin(), vz.end());
vz.erase(unique(vz.begin(), vz.end()), vz.end());
tmd = vz.size();
for(int i = 1; i <= tot; i ++)
{
// c[i] = 0;
Q[i].z = lower_bound(vz.begin(), vz.end(), Q[i].z) - vz.begin() + 1;
}
// puts("---------------");
cdq(1, tot);
for(int i = 1; i < q; i ++)
{
printf("%d\n", ans[i]);
}
}
}