码迷,mamicode.com
首页 > 其他好文 > 详细

poj 1436 线段树

时间:2015-04-21 01:37:45      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:

题意:给你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<cstring>
 3 #include<vector>
 4 #include<algorithm>
 5 #define FOR(i,s,t) for(int i=(s); i<(t); i++)
 6 using namespace std;
 7 const int maxn = 20000;
 8 #define lson l,m,rt<<1
 9 #define rson m+1,r,rt<<1|1
10 struct v_seg{
11     int s,t;
12     int x;
13 }ss[maxn];
14 int cover[maxn<<2];
15 int Hash[maxn];
16 vector<int> V[maxn];
17 void pushdown(int rt){
18     if(cover[rt]!=-1){
19         cover[rt<<1]=cover[rt<<1|1]=cover[rt];
20         cover[rt]=-1;
21     }
22 }
23 void update(int L,int R,int id,int l,int r,int rt){
24     if(L<=l&&r<=R){
25         cover[rt]=id;
26         return ;
27     }
28     pushdown(rt);
29     int m=(l+r)>>1;
30     if(L<=m) update(L,R,id,lson);
31     if(R>m) update(L,R,id,rson);
32 }
33 void query(int L,int R,int id,int l,int r,int rt){
34     if(cover[rt]!=-1){
35         if(Hash[cover[rt]]!=id){    //不被重复记录
36             V[cover[rt]].push_back(id);
37             Hash[cover[rt]]=id;
38         }
39         return ;
40     }
41     if(l==r) return ;
42     pushdown(rt);
43     int m=(l+r)>>1;
44     if(L<=m) query(L,R,id,lson);
45     if(R>m)  query(L,R,id,rson);
46 }
47 int cmp(v_seg a,v_seg b){
48     return a.x<b.x;
49 }
50 int main(){
51     int t,i,j,k,n,T,h;
52     #ifndef ONLINE_JUDGE
53     freopen("1.in","r",stdin);
54     #endif
55     scanf("%d",&T);
56     while(T--){
57         memset(cover,-1,sizeof(cover));
58         memset(Hash,-1,sizeof(Hash));
59         scanf("%d",&n);
60         for(i=0;i<n;i++)
61         {
62             scanf("%d%d%d",&ss[i].s,&ss[i].t,&ss[i].x);
63             ss[i].s<<=1;ss[i].t<<=1;V[i].clear();
64         }
65         sort(ss,ss+n,cmp);
66         for(i=0;i<n;i++){
67             query(ss[i].s,ss[i].t,i,0,16000,1);
68             update(ss[i].s,ss[i].t,i,0,16000,1);
69         }
70         for(i=0;i<n;i++)
71         {
72             sort(V[i].begin(), V[i].end());         //v[i]储存的是i号结点所能看到的线段编号
73         }
74     int ans=0;
75     for(i=0;i<n;i++)
76     {
77         int len = V[i].size();
78         for(k=0;k<len;k++)
79         {
80             for(j=k+1;j<len;j++)
81             {
82                 int a = V[i][k];
83                 int b = V[i][j];
84                 if(binary_search(V[a].begin(), V[a].end(), b))
85                 ans++;
86             }
87         }
88     }
89         printf("%d\n",ans);
90     }
91     return 0;
92 }

 

poj 1436 线段树

标签:

原文地址:http://www.cnblogs.com/cnblogs321114287/p/4443096.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!