poj 1436 线段树

题意:给你N条线段(垂直于x轴)的两个y坐标还有x坐标,问相互看到的三元组有多少个。
有点纠结就是,如果两个连线之间正好有一条线段的某个端点,这个也是不能计算的,所以这个端点就有意义了,所以就用上面那个题的做法,全部扩大二倍再用线段树。
Sample Input
1       //测试次数
5       //线段数目
0 4 4   //y1,y2,x
0 3 1
3 4 2
0 2 2
0 2 3
Sample Output

1

 

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath>
  6 #include<queue>
  7 #include<map>
  8 using namespace std;
  9 #define MOD 1000000007
 10 const int INF=0x3f3f3f3f;
 11 const double eps=1e-5;
 12 #define cl(a) memset(a,0,sizeof(a))
 13 #define ts printf("*****\n");
 14 #define lson l,mid,rt<<1
 15 #define rson mid+1,r,rt<<1|1
 16 #define root 1,n,1
 17 #define mid ((l+r)>>1)
 18 const int MAXN=20000;
 19 int n,m,t,Min,tt;
 20 int sum[MAXN<<2],col[MAXN<<2],hash[MAXN];
 21 
 22 vector<int> v[MAXN];
 23 struct node
 24 {
 25     int s,t,x;
 26     void in()
 27     {
 28         scanf("%d%d%d",&s,&t,&x);
 29         s<<=1,t<<=1;
 30     }
 31 }a[MAXN];
 32 bool cmp(node A,node B)
 33 {
 34     return A.x<B.x;
 35 }
 36 void pushdown(int rt)
 37 {
 38     if(col[rt]!=-1)
 39     {
 40         col[rt<<1]=col[rt<<1|1]=col[rt];
 41         col[rt]=-1;
 42     }
 43 }
 44 void update(int L,int R,int val,int l,int r,int rt)
 45 {
 46     if(l>=L&&r<=R)
 47     {
 48         col[rt]=val;
 49         return;
 50     }
 51     pushdown(rt);
 52     if(L<=mid) update(L,R,val,lson);
 53     if(R>mid) update(L,R,val,rson);
 54 }
 55 void query(int L,int R,int val,int l,int r,int rt){
 56     if(col[rt]!=-1){
 57         if(hash[col[rt]]!=val){ //防止重复覆盖
 58             v[col[rt]].push_back(val);
 59             hash[col[rt]]=val;
 60         }
 61         return ;
 62     }
 63     if(l==r) return ;
 64     pushdown(rt);
 65     if(L<=mid) query(L,R,val,lson);
 66     if(R>mid)  query(L,R,val,rson);
 67 }
 68 int main()
 69 {
 70     int i,j,k;
 71     #ifndef ONLINE_JUDGE
 72     freopen("1.in","r",stdin);
 73     #endif
 74     scanf("%d",&tt);
 75     while(tt--)
 76     {
 77         memset(col,-1,sizeof(col));
 78         memset(hash,-1,sizeof(hash));
 79         scanf("%d",&n);
 80         for(i=0;i<n;i++)
 81         {
 82             a[i].in();
 83             v[i].clear();
 84         }
 85         sort(a,a+n,cmp);
 86         for(i=0;i<n;i++)
 87         {
 88             query(a[i].s,a[i].t,i,0,16000,1);
 89             update(a[i].s,a[i].t,i,0,16000,1);
 90         }
 91         for(i=0;i<n;i++)
 92         {
 93             sort(v[i].begin(), v[i].end());         //v[i]储存的是i号结点所能看到的线段编号
 94         }
 95         int tot=0;
 96         for(i=0;i<n;i++)
 97         {
 98             int len=v[i].size();
 99             for(j=0;j<len;j++)
100             {
101                 for(k=j+1;k<len;k++)
102                 {
103                     int a1=v[i][j];
104                     int a2=v[i][k];
105                     if(binary_search(v[a1].begin(),v[a1].end(),a2)) tot++;
106                 }
107             }
108         }
109         printf("%d\n",tot);
110     }
111 }

 

posted @ 2015-04-21 08:42  miao_a_miao  阅读(153)  评论(0编辑  收藏  举报