POJ1436 Horizontally Visible Segments

来源:互联网 发布:js 大于等于 编辑:程序博客网 时间:2024/06/08 15:05
个人觉得比较坑的线段树的题目,因为题意我就理解了半天

题意:

有N根竖直的杆子,每个杆子都用一个长度,两根杆子可以想见意味着两个杆子在水平

方向上存在一条直线,使得该直线连接两个杆子,并且该水平直线和其他的杆子都没

交点,问一共有多少对三根杆子的组合使得杆子两两可见。这里要注意的地方有一点是如果只是两个杆子的边界相同,只要他们中间没有间隔他们也能相互看见,比如说y坐标为1——3和3——4是可以相互看见的,但是如果他们中间有一个2——3的杆子他们还是看不见,但是如果3——4的杆子在1——3和2——3之间那么还是没法阻挡,所以题意好坑。个人觉得不科学,也不符合实际。

解题思路就是把所有的线按x轴排序,然后依次向y轴映射,然后覆盖,

不过遇坑爹的边界设定,线段树的设计就要略有改进,也就是把所有的y值乘以2,这样的话就算1——3和2——3之间有3——4就会变为2——6,4——6,6——8那么实际上3——4它也只会覆盖6——8而不会将5覆盖保证了1——3和2——3之间的正常判定。

#include <iostream>#include <cstring>#include <cstdlib>#include <cmath>#include <vector>#include <cstdio>#include <queue>#include <map>#include <algorithm>#include <stack>typedef long long LL;using namespace std;const int  mx = 16005;int a[mx * 3];bool ma[mx >> 1][mx >> 1];int n,qr,ql,date;struct K{    int l,r,x;} S[mx];bool cmp(K  a,K b){    return a.x < b.x;}void update(int o = 1,int L = 0,int R = mx){    if(ql <=  L && qr >= R)    {        a[o] = date;//         printf("o = %d L =%d R = %d date =%d\n",o,L,R,date);        return;    }    int mid = (R + L) >> 1;    if(a[o] != 0)    {        a[o << 1] = a[o << 1 | 1] = a[o];        a[o] = 0;    }//    printf("o = %d L =%d R = %d  ql = %d qr =%d date = %d mid = %d\n",o,L,R,ql,qr,date,mid);    if(ql <= mid) update(o << 1,L,mid);    if(qr > mid)  update(o << 1|1,mid + 1,R);}void qu(int o = 1,int L = 0,int R = mx){//     printf("o = %d L =%d R = %d\n",o,L,R);    if(a[o] != 0)    {//        printf("a[] = %d date =%d\n",a[o],date);        ma[a[o]][date] = ma[date][a[o]] = true;        return;    }    if(R == L) return;//  printf("PPPPPP\n");    int mid = (R + L) >> 1;    if(ql <= mid) qu(o << 1,L,mid);    if(qr > mid) qu(o << 1|1,mid + 1,R);}int main (){    int T,i,h,k,g,j,ans;    scanf("%d",&T);    while (T--)    {        memset(a,0,sizeof(a));        memset(ma,false,sizeof(ma));        ans = 0;        scanf("%d",&n);        for(i = 1; i <= n; i++)            scanf("%d%d%d",&S[i].l,&S[i].r,&S[i].x);        sort(S + 1,S + n + 1,cmp);        for(i = 1; i <= n; i++)        {            qr = S[i].r*2;            ql = S[i].l*2;            date = i;            qu();            update();        }        for(i = 1; i <= n; i++)            for(j = i + 1; j <= n; j++)                if(ma[i][j])                    for(k = j; k <= n; k++)                        if(ma[i][k] && ma[j][k])                            ans++;        printf("%d\n",ans);    }}

0 0
原创粉丝点击