首先对线段按照x坐标排序,对于每一条线段的y坐标都乘以2,因为如果有两条同一x坐标的线段分别y坐标为1-2,3-4 2和3之间其实是可以通过的.如果不乘二就会被忽略掉了.
然后按顺序插入每一条线段,每条线段染一种颜色,对于后面插入的线段i首先查询下 [yi1,yi2]区间里的能看见的颜色,这些颜色的线段就可以看见线段i,然后把这些颜色的线段的vector里插入i.
因为里面有很多重复的数据,所以用一下unique.
最后枚举一下.
#include <iostream>
#include <cstdio>
#include <memory.h>
#include <algorithm>
#include <vector>
using namespace std;
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 | 1
const int maxn=17000;
int segs[maxn*3], n, m;
vector<int>vs[maxn/2];
struct segment{
int y1,y2,x;
bool operator<(const segment & rhs)const{
return x < rhs.x;
}
}ss[maxn/2];
void build(int l,int r,int rt){
segs[rt] = 0;
if (l == r){
return;
}
int m = (l + r) >> 1;
build(lson), build(rson);
}
void query(int L, int R, int l, int r, int rt, int id){
if (segs[rt]){
vs[segs[rt]].push_back(id);
return;
}
if(l == r) return;
if(segs[rt]){
segs[rt << 1] = segs[rt << 1 | 1] = segs[rt];
segs[rt]=0;
}
int m = (l + r) >> 1;
if(L <= m)query(L, R, lson, id);
if(R > m)query(L, R, rson, id);
}
void update(int L, int R, int l, int r, int rt, int id){
if (L <= l && r <= R){
segs[rt] = id;
return ;
}
int m = (l + r) >> 1;
if(segs[rt]){
segs[rt << 1] = segs[rt << 1 | 1] = segs[rt];
segs[rt]=0;
}
if(L <= m)update(L, R, lson, id);
if(R > m)update(L, R, rson, id);
}
int main(){
int t;
scanf("%d",&t);
while (t--){
scanf("%d",&n);
int maxy=0;
for (int i=1;i<=n;++i){
scanf("%d%d%d", &ss[i].y1, &ss[i].y2, &ss[i].x);
ss[i].y1 = (ss[i].y1 << 1) + 1;
ss[i].y2 = (ss[i].y2 << 1) + 1;
maxy = max(maxy, max(ss[i].y2, ss[i].y1));
vs[i].clear();
}
build(1, maxy, 1);
sort(ss + 1, ss + n + 1);
for (int i = 1; i <= n; ++i){
query(ss[i].y1, ss[i].y2, 1, maxy, 1, i);
update(ss[i].y1, ss[i].y2, 1, maxy, 1, i);
}
int ans = 0;
for (int i = 1 ; i <= n; ++i){
vs[i].erase(unique(vs[i].begin(),vs[i].end()), vs[i].end());
}
for (int i = 1 ; i <= n; ++i){
int si = vs[i].size();
for (int j = 0; j < si; ++j){
for (int k = j + 1; k < si; ++k){
int sk = vs[vs[i][j]].size();
for (int l = 0; l < sk; ++l){
if (vs[vs[i][j]][l] == vs[i][k]){
ans++;
break;
}
}
}
}
}
printf("%d\n",ans) ;
}
return 0;
}