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 }

 

你可能感兴趣的:(poj)