第三次作业

639.线段树-贴海报 (10分)
C时间限制:3000 毫秒 |  C内存限制:3000 Kb
题目内容:
由10^7块1x1的玻璃构成1x10^7的海报墙,每个海报完整地覆盖几块玻璃,海报的宽度可以不同。后来的人可以覆盖
前人的海报。一张海报如果有没被覆盖的部分,则称为可视海报。你的任务是找出有多少可视海报。
输入描述
第一行是测试的总数c,接下来的行是各测试用例。
每个测试的第一行是海报的总数n, n<=10000, 然后是n个按先后顺序贴的海报的位置li, ri. 满足1<=li<=ri<=10^7。

输出描述
每个测试的可视海报数目

输入样例
1
5
1 4
2 6
8 10
3 4
7 10

输出样例
4


 

代码:

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
#define L(rt) (rt<<1)
#define R(rt) (rt<<1|1)
const int N = 1e5+10;
int flag;
struct Tree{
    int l,r;
    bool vis;
}tree[N<<2];

struct Point{
    int id,x;
}post[N<<2];

int cmp1(Point a,Point b){
    return a.x<b.x;
}
 
int cmp2(Point a,Point b){
    if(a.id == b.id)
        return a.x < b.x;
    return a.id >b.id;     
}

void PushUp(int rt){
    tree[rt].vis = tree[L(rt)].vis&&tree[R(rt)].vis;
}

void build(int L,int R,int rt){
    tree[rt].l = L;
    tree[rt].r = R;
    tree[rt].vis = 0;
    if(tree[rt].l == tree[rt].r)
        return ;
    int mid = (L+R)>>1;
    build(L,mid,L(rt));
    build(mid+1,R,R(rt));    
}

void query(int L,int R,int rt){
    if(tree[rt].vis)
        return ;
    if(tree[rt].l ==L&& tree[rt].r==R){
        tree[rt].vis = 1;
        flag=1;
        return ;
    }
    int mid = (tree[rt].l + tree[rt].r)>>1;
    if(R<=mid)
        query(L,R,L(rt));
    else if(L>=mid+1)
        query(L,R,R(rt));
    else{
        query(L,mid,L(rt));
        query(mid+1,R,R(rt));
    }
    PushUp(rt);
}


int main(){
    int t,n;
    cin>>t;
    while(t--){
        scanf("%d",&n);
        for(int i=0;i<2*n;i+=2){
            scanf("%d%d",&post[i].x,&post[i+1].x);
            post[i].id = post[i+1].id = i;
        }    
        sort(post,post+2*n,cmp1);
        int tot = 0,pre = 0;
        for(int i=0;i<2*n;i++){
            if(post[i].x == pre)
                post[i].x = tot;
            else{
                pre = post[i].x;
                post[i].x = ++tot;
            }
        }
        build(1,2*n,1);
        sort(post,post+2*n,cmp2);
        int ans = 0;
        for(int i=0;i<2*n;i=i+2){
            int l = post[i].x;
            int r = post[i+1].x;
            flag = 0;
            query(l,r,1);
            if(flag)
                ans++;
        }
        
        cout<<ans<<endl;
        
    }
    return 0;
}

 

posted @ 2019-10-04 16:56  sqsq  阅读(354)  评论(0编辑  收藏  举报