poj 2528 线段树 离散化

来源:互联网 发布:java开发吃处理器吗 编辑:程序博客网 时间:2024/05/16 01:25

题目连接:http://poj.org/problem?id=2528

题目大意:在一面墙上贴海报,墙很长,后面贴上去的海报要覆盖掉之前贴上去的海报,现在向墙上逐一的贴海报,问到最后墙上可以看见的海报有几种?

方法:线段树,离散化

代码:

#include <iostream>#include <cstdio>#include <algorithm>#include <cstring>using namespace std;#define maxn 10005struct node{    int l, r, d;}v[maxn<<2];struct vir{    int val, pos;    bool operator < (const vir& b)const    {        return val<b.val;    }}line[maxn<<2];int set[maxn<<1][2], visited[maxn<<1], ans;void build(int l, int r, int n){    v[n].l = l, v[n].r = r;    v[n].d = -1;    if (l==r)        return ;    int mid = (v[n].l + v[n].r)>>1;    build(l, mid, n<<1);    build(mid+1, r, n<<1|1);}void pushdown(int n){    if (v[n].d!=-1)    {        v[n<<1].d = v[n].d;        v[n<<1|1].d = v[n].d;        v[n].d = -1;    }}void update(int l, int r, int n, int d){    if (l<=v[n].l && v[n].r<=r)    {        v[n].d = d;        return ;    }    pushdown(n);    int mid = (v[n].l + v[n].r)>>1;    if (r<=mid)        update(l, r, n<<1, d);    else if (l>mid)        update(l, r, n<<1|1, d);    else    {        update(l, mid, n<<1, d);        update(mid+1, r, n<<1|1, d);    }}void find(int l, int r, int n){    if (v[n].d>=0 || l==r)    {        if (v[n].d>=0 && !visited[v[n].d])        {            visited[v[n].d] = 1;            ++ ans;        }        return ;    }    pushdown(n);    int mid = (v[n].l + v[n].r)>>1;    find(l, mid, n<<1);    find(mid+1, r, n<<1|1);}int main(){    int ncase, n;    cin >> ncase;    while (ncase--)    {        cin >> n;        for (int i=0; i<n; ++i)        {            scanf("%d%d", &set[i][0], &set[i][1]);            line[i<<1].val = set[i][0];            line[i<<1].pos = -(i+1);            line[i<<1|1].val = set[i][1];            line[i<<1|1].pos = i+1;        }        sort(line, line+2*n);        int tp = 1, temp = line[0].val;        for (int i=0; i<2*n; ++i)//离散化        {            if (temp!=line[i].val)            {                ++ tp;                temp = line[i].val;            }            if (line[i].pos < 0)                set[ -line[i].pos-1 ][0] = tp;            else                set[ line[i].pos-1 ][1] = tp;        }        build(1, tp, 1);        for (int i=0; i<n; ++i)            update(set[i][0], set[i][1], 1, i);//更新        memset(visited, 0, sizeof(visited));        ans = 0;        find(1, tp, 1);//统计        printf("%d\n", ans);    }    return 0;}

原创粉丝点击