zoukankan      html  css  js  c++  java
  • POJ 1436.Horizontally Visible Segments-线段树(区间更新、端点放大2倍)

    水博客,水一水。

    Horizontally Visible Segments
    Time Limit: 5000MS   Memory Limit: 65536K
    Total Submissions: 6290   Accepted: 2287

    Description

    There is a number of disjoint vertical line segments in the plane. We say that two segments are horizontally visible if they can be connected by a horizontal line segment that does not have any common points with other vertical segments. Three different vertical segments are said to form a triangle of segments if each two of them are horizontally visible. How many triangles can be found in a given set of vertical segments? 


    Task 

    Write a program which for each data set: 

    reads the description of a set of vertical segments, 

    computes the number of triangles in this set, 

    writes the result. 

    Input

    The first line of the input contains exactly one positive integer d equal to the number of data sets, 1 <= d <= 20. The data sets follow. 

    The first line of each data set contains exactly one integer n, 1 <= n <= 8 000, equal to the number of vertical line segments. 

    Each of the following n lines consists of exactly 3 nonnegative integers separated by single spaces: 

    yi', yi'', xi - y-coordinate of the beginning of a segment, y-coordinate of its end and its x-coordinate, respectively. The coordinates satisfy 0 <= yi' < yi'' <= 8 000, 0 <= xi <= 8 000. The segments are disjoint.

    Output

    The output should consist of exactly d lines, one line for each data set. Line i should contain exactly one integer equal to the number of triangles in the i-th data set.

    Sample Input

    1
    5
    0 4 4
    0 3 1
    3 4 2
    0 2 2
    0 2 3

    Sample Output

    1

    题意:输入n表示有n条线段,n行每行输入y1,y2,x表示线段的下端点,上端点以及线段的位置(横坐标位置),对于第i条线段和第k条线段如果用一条平行线能够经过它们并且在它们之间不经过其他线段,则称这两条线段互为可见,求有多少3条线段两两可见(懒得写题意,直接贴的别人的)

    代码:

      1 //线段树区间更新,端点放大2倍
      2 #include<iostream>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<algorithm>
      6 #include<cmath>
      7 #include<cstdlib>
      8 using namespace std;
      9 typedef long long ll;
     10 const int maxn=8e3+10;
     11 
     12 #define lson l,m,rt<<1
     13 #define rson m+1,r,rt<<1|1
     14 
     15 int col[maxn<<2];
     16 bool mp[maxn][maxn];
     17 
     18 struct node{
     19     int y1,y2,x,id;
     20 }line[maxn];
     21 
     22 bool cmp(node a,node b)
     23 {
     24     return a.x<b.x;
     25 }
     26 
     27 void init()
     28 {
     29     memset(mp,0,sizeof mp);
     30     memset(line,0,sizeof line);
     31     memset(col,0,sizeof col);
     32 }
     33 
     34 void pushdown(int rt)
     35 {
     36     if(col[rt]){
     37         col[rt<<1]=col[rt<<1|1]=col[rt];
     38         col[rt]=0;
     39     }
     40 }
     41 
     42 void update(int L,int R,int c,int l,int r,int rt)
     43 {
     44     if(L<=l&&r<=R){
     45         col[rt]=c;
     46         return ;
     47     }
     48 
     49     pushdown(rt);
     50     int m=(l+r)>>1;
     51     if(L<=m) update(L,R,c,lson);
     52     if(R> m) update(L,R,c,rson);
     53 }
     54 
     55 void query(int L,int R,int c,int l,int r,int rt)
     56 {
     57     if(col[rt]){
     58         mp[c][col[rt]]=1;
     59         return ;
     60     }
     61 
     62     if(l==r){
     63         return ;
     64     }
     65 
     66     int m=(l+r)>>1;
     67     if(L<=m) query(L,R,c,lson);
     68     if(R> m) query(L,R,c,rson);
     69 }
     70 
     71 int main()
     72 {
     73     int t;
     74     scanf("%d",&t);
     75     while(t--){
     76         init();
     77         int n;
     78         scanf("%d",&n);
     79         int N=-1;
     80         for(int i=1;i<=n;i++){
     81             scanf("%d%d%d",&line[i].y1,&line[i].y2,&line[i].x);
     82             line[i].id=i;line[i].y1*=2;line[i].y2*=2;N=max(N,max(line[i].y1,line[i].y2));
     83         }
     84         sort(line+1,line+1+n,cmp);//按x轴从小到大排序,降维,只对y轴进行建树
     85         for(int i=1;i<=n;i++){
     86             query(line[i].y1,line[i].y2,line[i].id,0,N,1);
     87             update(line[i].y1,line[i].y2,line[i].id,0,N,1);
     88         }
     89         int ans=0;
     90         for(int i=1;i<=n;i++){
     91             for(int j=1;j<=n;j++){
     92                 if(mp[i][j]){
     93                     for(int k=1;k<=n;k++){
     94                         if(mp[i][k]&&mp[k][j]) ans++;
     95                     }
     96                 }
     97             }
     98         }
     99         printf("%d
    ",ans);
    100     }
    101 }
  • 相关阅读:
    string基本字符系列容器(一)
    HDU 1541 star (树状数组)
    NKOI 1321--数列操作问题(裸BIT)
    树状数组(BIT)初学
    vector向量容器
    C++ STL概述
    2015年,为ACM奋斗的一年
    kuangbin带你飞,矩阵(简单数学推导题)
    hust 1009 Sum the K-th
    hust 1223 Friends
  • 原文地址:https://www.cnblogs.com/ZERO-/p/10951596.html
Copyright © 2011-2022 走看看