poj1436水平可见线

还是线段树区间更新,这次不需要对线段离散化,但是要把线段纵坐标*2,可以举例模拟

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
#define maxn 8005
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
struct Edge{
    int x,y1,y2,id;
    bool operator<(const Edge& a)const{
        return x<a.x;
    }
}edge[maxn];
bool mp[maxn][maxn];
int color[maxn*2<<2],m,ans;
inline void pushdown(int rt){
    if(color[rt]){
        color[rt<<1]=color[rt<<1|1]=color[rt];
        color[rt]=0;
    }
}
void query(int L,int R,int id,int l,int r,int rt){
    if(color[rt]){
        mp[id][color[rt]]=1;
        return;
    }    
    if(l==r) return;
    int m=l+r>>1;
    if(L<=m) query(L,R,id,lson);
    if(R>m) query(L,R,id,rson);
}
void update(int L,int R,int id,int l,int r,int rt){
    if(L<=l && R>=r){
        color[rt]=id;
        return;
    }
    pushdown(rt);
    int m=l+r>>1;
    if(L<=m) update(L,R,id,lson);
    if(R>m) update(L,R,id,rson);
}

int main(){
    int T,n;
    cin >> T;
    while(T--){
        m=-1;
        ans=0;
        memset(color,0,sizeof color);
        memset(mp,0,sizeof mp);
        cin >> n;
        for(int i=1;i<=n;i++){
            scanf("%d%d%d",&edge[i].y1,&edge[i].y2,&edge[i].x);
            edge[i].y1*=2;
            edge[i].y2*=2;
            edge[i].id=i;
            m=max(edge[i].y1,m);
            m=max(edge[i].y2,m);
        } 
        sort(edge+1,edge+1+n);
        
        for(int i=1;i<=n;i++){
            query(edge[i].y1,edge[i].y2,edge[i].id,0,m,1);
            update(edge[i].y1,edge[i].y2,edge[i].id,0,m,1);
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                if(mp[i][j])
                    for(int k=1;k<=n;k++)
                        if(mp[i][k] && mp[j][k])
                            ans++;
        printf("%d\n",ans);
    }    
}

 

posted on 2018-11-06 13:54  zsben  阅读(172)  评论(0编辑  收藏  举报

导航