`
暴风雪
  • 浏览: 388761 次
  • 性别: Icon_minigender_2
  • 来自: 杭州
社区版块
存档分类
最新评论

[离散化+线段树]poj2528

 
阅读更多

题意

      给出每个海报的位置,问最后没有被完全覆盖的海报有多少张

思路

      这里给的海报的端点值很大,需要离散化之后再用线段树求解。离散化写挫被坑了好多发,注意这三组数据。

3

3

3 4

1 3

4 10

//答案是2

 

3

1 5

1 3

4 5

//答案是2

 

3

1 10

1 3

6 10

//答案是3

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int nMax = 100000;
struct{
    int l,r,val;  //-1杂色  0无色  1---k纯色
}node[nMax * 3];

struct{
    int a,b;
}ad[nMax];
int num[4*nMax];
int hash[10000010];
void build(int l ,int r ,int u){
    node[u].l = l;
    node[u].r = r;
    node[u].val = 0;
    if(l == r)return;
    int m = (l + r)>>1;
    build(l ,m ,u*2);
    build(m+1 ,r ,u*2+1);
}

void update(int left ,int right ,int val ,int u){
    if(left == node[u].l && right == node[u].r){
//    cout<<left <<" "<<right <<" "<<u<<endl;
        node[u].val = val;
        return;
    }
    if(node[u].val != -1){
        node[u*2].val = node[u*2+1] .val = node[u].val;
        node[u].val = -1;
    }
    int m = (node[u].l + node[u].r)>>1;
    if(right <= m){
        update(left ,right ,val ,u*2);
        return;
    }
    if(left >= m+1){
        update(left ,right ,val ,u*2+1);
        return;
    }
    update(left ,m ,val ,u*2);
    update(m+1 ,right ,val ,u*2+1);
}

void query(int left ,int right ,int u){
//    cout<<left <<" e e "<<right<<endl;
    if(node[u].val != -1){
//            cout<<"get\n";
        num[node[u].val] = 1;
        return;
    }
    int m =(node[u].l + node[u].r)>>1;
    if(left <= m){
       query(left ,min(m ,right) ,u*2);
    }
    if(right >= m+1){
        query(max(m+1 ,left) ,right ,u*2 + 1);
    }
}
int main(){
    int tcs ,n ,i ,k;
    scanf("%d",&tcs);
    while(tcs--){
        scanf("%d",&n);
        k = 0;
        for(i = 1 ;i <= n ;i++){
            scanf("%d%d",&ad[i].a,&ad[i].b);
            num[k++] = ad[i].a;
            num[k++] = ad[i].b;
        }
        sort(num ,num + k);
        memset(hash,0,sizeof(hash));
        int tmp = 0;
        hash[num[0]] = 1;
        int nk = 2;
        for(i=1 ;i < k ;i++){
            if(num[i] - num[i-1] > 1)tmp++;
            if(!hash[num[i]]){
                    hash[num[i]] = nk + tmp;
                    nk++;
            }
//            if(num[i]!=num[i-1])hash[num[i]] = (i + 1) + tmp;
        }
        for(i = 1 ;i <= n ;i++){
            ad[i].a = hash[ad[i].a];
            ad[i].b = hash[ad[i].b];
        }
        build(1 ,nk + tmp,1);
//        cout<<" -------------\n";
        for(i = 1 ;i <= n;i++){
//            cout<<ad[i].a<<" "<<ad[i].b<<endl;
            update(ad[i].a ,ad[i].b ,i ,1);
//            cout<<endl<<endl;
        }
        memset(num ,0 ,sizeof(num));
        int ans = 0;
        query(1 ,nk + tmp,1);
        for(i = 1 ;i <= n ;i++){
            if(num[i])ans++;
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

 

分享到:
评论

相关推荐

    POJ2528-Mayor's posters【区间映射压缩(离散化)+线段树】

    POJ2528-Mayor's posters 【区间映射压缩(离散化)+线段树】 解题报告+AC代码 http://hi.csdn.net/!s/83XZJU ========&gt; 我的所有POJ解题报告链接: http://blog.csdn.net/lyy289065406/article/details/6642573

    线段树题目

    - **POJ 1151**:结合了线段树和离散化的技巧来求解矩形面积的并集。这需要对输入的坐标进行离散化处理,以减少空间复杂度,并使用线段树维护区间信息。 - **POJ 1177**:求解矩形周长的并集。此题与POJ 1151类似,...

    ACMer需要掌握的算法讲解 (2).docx

    * 坐标离散化:POJ3429 * 代码快速写成,精简但不失风格:POJ2525、POJ1684、POJ1421、POJ1048、POJ2050、POJ3306 * 保证正确性和高效性:POJ3434 六、动态规划 * 需要用数据结构优化的动态规划:POJ2754、POJ3378...

    ACMer需要掌握的算法讲解.docx

    1. 坐标离散化(poj3429) 2. 几何公式 3. 叉积和点积的运用(如线段相交的判定,点到线段的距离等) 六、动态规划 1. 需要用数据结构优化的动态规划 2. 四边形不等式理论 七、综合题 1. 组合数学 2. 博奕论 3. ...

    POJ 分类题目

    - **定义**:叉积和点积的应用,如线段相交判定、点到线段的距离等。 - **示例题目**: - poj2031 - poj1039 - **应用场景**:适用于几何图形的判断和计算。 **3. 多边型的算法** - **定义**:包括多边形的面积...

    poj2482.zip_Stars in Your Window_星星亮度

    以每个星星为中心,得到可以罩住它的矩形的左下角的范围,这些范围...离散化x坐标,将矩形的横线段按y升序排列。一根横线从下向上扫描,遇到矩形下边将对应x范围都加亮度,上边框减亮度。每次用线段树更新和求最大值。

    2010FZUACM_高级数据结构习题讲解1

    在POJ2482 Stars in Your Window问题中,由于数值范围很大,需要先离散化处理,然后将二维问题转化为一维线段树。通过插入和删除操作,可以解决求前k项最大和的问题。此外,要注意处理边界条件,如输入数据可能在...

    广工《算法和高级数据结构教程课程设计》

    - 线段树建立:通过离散化后的点集建立线段树,每个线段存储点区间内的最高频次。 4. 运行测试: - 测试数据:提供具体的输入输出样例。 - 运行环境:Windows 8操作系统,使用Code::Blocks集成开发环境进行测试...

    浙江大学ACM模板 计算几何,图论,数据结构,经典题的模板

    7.2 线段树 147 7.3 并查集 151 7.4 树状数组 152 7.5 点树 154 7.6 STL 156 7.7 离散化 157 8.图论 158 8.0 2-SAT 158 8.2 寻找Euler回路 163 8.3 拓扑排序 163 8.4 差分约束系统 164 8.5 笛卡尔树 165 8.6 LCA和...

    挑战程序设计竞赛(第2版)

    3.2.5 坐标离散化 3.3 活用各种数据结构 3.3.1 线段树 3.3.2 Binary Indexed Tree 3.3.3 分桶法和平方分割 3.4 熟练掌握动态规划 3.4.1 状态压缩DP 3.4.2 矩阵的幂 3.4.3 利用数据结构高效求解 3.5 借助水流解决问题...

    常用算法.docx

    4. **计算几何中的算法**:如坐标离散化、扫描线算法和半平面交等,用于处理几何对象的计算问题。 **C++标准模板库的应用**: C++的STL(Standard Template Library)包含容器、迭代器、算法和函数对象,为编程...

Global site tag (gtag.js) - Google Analytics