能用线段树做,但是n3也过
把坐标 * 2 来区别,端点和非端点
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
struct edge
{
int y1,y2,x,id;
}E[8008];
int node[8008*8];
bool ok[8008][8008];
inline bool cmp(edge a,edge b)
{
return a.x<b.x;
}
void push_down(int root)
{
if (node[root] == 0) return;
node[root*2] = node[root];
node[root*2+1] = node[root];
node[root] = 0;
}
void solve(int root,int xbegin,int xend,int qbegin,int qend,int id)
{
if (qend < xbegin||xend<qbegin) return;
if (qbegin <= xbegin && xend <= qend)
{
if (node[root]!=0)
{
ok[id][node[root]] = true;
ok[node[root]][id] = true;
node[root] = id;
return;
}
node[root] = id;
}
else
push_down(root);
int mid = (xbegin + xend) /2;
if (xbegin == xend) return;
solve(root*2,xbegin,mid,qbegin,qend,id);
solve(root*2+1,mid+1,xend,qbegin,qend,id);
}
int main()
{
int T;
cin >> T;
int y1,y2,x;
while (T--)
{
int N;
cin >> N;
memset(node,0,sizeof(node));
memset(ok,false,sizeof(ok));
int max_y = 0;
for (int i = 1; i<=N; i++)
{
scanf("%d%d%d",&y1,&y2,&x);
E[i].y1 = y1;
E[i].y2 = y2;
E[i].x = x;
E[i].id = i;
max_y = max(max_y,y2);
}
sort(E+1,E+N+1,cmp);
int ans = 0;
for (int i = 1;i<=N;i++)
{
solve(1,0,2 * max_y,E[i].y1 * 2,E[i].y2 * 2,E[i].id);
}
for (int i = 1; i<=N; i++)
for (int j = i+1; j<=N; j++)
if (ok[i][j])
for (int k = j+1;k<=N; k++)
{
if (ok[i][j]&&ok[i][k]&&ok[j][k]) ans++;
}
cout <<ans<<endl;
}
}