/* poj 1436 题意: 给出N(N <= 8000)条垂直线段,如果两条线段在水平方向上连一条线之后不和其他任 何垂直线段相交,那么我们称这两条线段水平可见,如果三条垂直线段两两水平可见 ,则称其为一个三角,问着N条线段能组成多少三角。 解法: 线段树记录线段的id号。先将每一条线段按照x坐标排序,然后对于每一条线段, 先查询之前在它覆盖的区域内能看见哪些线段没有被完全覆盖,然后再用这条线段去更新。 最后暴力统计,*/
//ps:太弱。。。且一直纠结于为什么要将y坐标*2.。。终于发现了,,0,2,2,3,4,2这两组数据中间是可以通过的,但是中间确实可以通过...所以*2就能解决这个问题..^_^
//这题其实也不难...线段树+枚举...额,,偶太弱>_<
#include <iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<vector> using namespace std; typedef struct even{int y1,y2,x;}even; #define FOR(i,s,t) for(int i=(s); i<(t); i++) #define BUG puts("here!!!") #define STOP system("pause") #define file_r(x) freopen(x, "r", stdin) #define file_w(x) freopen(x, "w", stdout) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define maxn 16666 even edge[maxn]; int col[maxn<<2]; int seg[maxn<<2]; int hash[maxn+1]; vector<int>V[maxn]; int cmp( const void *a , const void *b ) { struct even *c = (even *)a; struct even *d = (even *)b; return c->x - d->x; } void pushdown(int rt){ if(col[rt]!=-1){ col[rt<<1|1]=col[rt<<1]=col[rt]; col[rt]=-1; } } void update(int c,int L,int R,int l,int r,int rt){ if(l>=L&&r<=R){ col[rt]=c; return ; } pushdown(rt); if(l==r) return ; int m=(l+r)>>1; if(L<=m) update(c,L,R,lson); if(R>m) update(c,L,R,rson); } void query(int c,int L,int R,int l,int r,int rt){ if(col[rt]!=-1){ if(hash[col[rt]]!=c){ V[col[rt]].push_back(c); hash[col[rt]]=c; } return ; } pushdown(rt); if(l==r) return ; int m=(l+r)>>1; if(L<=m){ query(c,L,R,lson); } if(R>m){ query(c,L,R,rson); } } int main(){ int d,n; scanf("%d",&d); while(d--){ scanf("%d",&n); for(int i=0;i<n;i++){ scanf("%d%d%d",&edge[i].y1,&edge[i].y2,&edge[i].x); edge[i].y1<<=1; edge[i].y2<<=1; V[i].clear(); } qsort(edge,n,sizeof(edge[0]),cmp); memset(col,-1,sizeof(col)); memset(hash,-1,sizeof(hash)); for(int i=0;i<n;i++){ query(i,edge[i].y1,edge[i].y2,0,maxn,1); update(i,edge[i].y1,edge[i].y2,0,maxn,1); } int sum=0; /* FOR(ii,0,n) { FOR(jj,0,V[ii].size()){ printf("%d ",V[ii][jj]); } puts(""); } */ for(int i=0;i<n;i++){ for(int j=0;j<V[i].size();j++){ int k=V[i][j]; for(int t=0;t<V[i].size();t++){ for(int w=0;w<V[k].size();w++) if(V[i][t]==V[k][w]) sum++; } } } printf("%d\n",sum); } return 0; }