poj1436

  1 /*
  2 题意:给你n条垂直线段,问有多少组三个线段,两两可见,
  3 可见定义为对于两条线段有一条水平线段连接,不经过任意其他线段;
  4 
  5 线段树建图,然后爆力判有几组(不知道效率如何);
  6 从左到右扫描,先判断该区间内有可以连接哪几条线段,建图;
  7 然后再插入;
  8 
  9 问题:对于[1,4],[1,2],[3,4],[1,4]
 10 如果直接1-2,3-4覆盖,当用1-4query的时候,
 11 会发现不存在(2,3)区域的标记,
 12 解决方法,每个点之间都插入一个点,用偶数表示原先的点,
 13 用奇数表示点之间的区域,0,1,2,3,4   
 14                     0   1   2
 15                         
 16 */
 17 #include<cstdio>
 18 #include<cstring>
 19 #include<cstdlib>
 20 #include<algorithm>
 21 #include<iostream>
 22 #include<cmath>
 23 #include<vector>
 24 #define lson l,m,rt<<1
 25 #define rson m+1,r,rt<<1|1
 26 using namespace std;
 27 const int N=8000+10;
 28 struct Edge{
 29     int l,r,idx;
 30     Edge(){}
 31     Edge(int a,int b,int c):l(a),r(b),idx(c){}
 32     void output(){
 33         cout<<l<<" "<<r<<" "<<idx<<endl;
 34     }
 35 };
 36 vector<Edge> g[N];
 37 vector<int> mz[N];
 38 bool vis[N][N];
 39 int n;
 40 int col[N<<3];//要扩大
 41 void pushdown(int rt){
 42     if (col[rt]!=-1){
 43         col[rt<<1]=col[rt<<1|1]=col[rt];
 44         col[rt]=-1;
 45     }
 46 }
 47 void pushup(int rt){
 48     if (col[rt<<1]!=col[rt<<1|1]){
 49         col[rt]=-1;
 50     }else col[rt]=col[rt<<1];
 51 }
 52 void update(int L,int R,int v,int l,int r,int rt){
 53     if (L<=l && r<=R){
 54         col[rt]=v;
 55         return;
 56     }
 57     pushdown(rt);
 58     int m=(l+r)>>1;
 59     if (L<=m) update(L,R,v,lson);
 60     if (m< R) update(L,R,v,rson);
 61     pushup(rt);
 62 
 63 }
 64 void query(int L,int R,int v,int l,int r,int rt){
 65 
 66     if (L<=l && r<=R && col[rt]!=-1){
 67         if (col[rt]==0) return ;
 68         if (vis[v][col[rt]]==0){
 69             mz[v].push_back(col[rt]);
 70             mz[col[rt]].push_back(v);
 71             vis[v][col[rt]]=1;
 72             vis[col[rt]][v]=1;
 73         }
 74         return ;
 75     }
 76     if (l==r) return;
 77     pushdown(rt);
 78     int m=(l+r)>>1;
 79     if (L<=m) query(L,R,v,lson);
 80     if (m< R) query(L,R,v,rson);
 81 }
 82 void work(){
 83     memset(col,0,sizeof(col));
 84     for (int i=0;i<=n;i++) for (int j=0;j<=n;j++) vis[i][j]=0;
 85     for (int i=0;i<N;i++){
 86         if (g[i].size()!=0){
 87             for (int j=0;j<g[i].size();j++){
 88                 Edge u=g[i][j];
 89                 query(u.l*2,u.r*2,u.idx,0,N*2-1,1);
 90             }
 91             for (int j=0;j<g[i].size();j++){
 92                 Edge u=g[i][j];
 93                 update(u.l*2,u.r*2,u.idx,0,N*2-1,1);
 94             }
 95         }
 96     }
 97 
 98     int ret=0;
 99     for (int i=1;i<=n;i++){
100         for (int j=0;j<mz[i].size();j++){
101             int c=mz[i][j];
102             for (int k=0;k<mz[c].size();k++){
103                 int w=mz[c][k];
104                 if (vis[w][i]) ret++;
105             }
106         }
107     }
108     printf("%d\n",ret/6);
109 }
110 void read(){
111     int x,y1,y2;
112     for (int i=0;i<N;i++) {
113         g[i].clear();mz[i].clear();
114     }
115     for (int i=0;i<n;i++){
116         scanf("%d%d%d",&y1,&y2,&x);
117         g[x].push_back(Edge(y1,y2,i+1));
118     }
119 }
120 int main(){
121     int T;scanf("%d",&T);
122     while (T--){
123         scanf("%d",&n);
124         read();
125         work();
126     }
127 
128 }
129 /*
130 1
131 5
132 0 4 1
133 1 3 2
134 1 3 3
135 2 4 3
136 0 5 4
137 */

 

posted @ 2013-05-15 20:21  Rabbit_hair  阅读(527)  评论(0编辑  收藏  举报