poj 2528 线段树区间合并

原创 2018年04月17日 20:02:23

点击打开链接 poj 2528

Description

The citizens of Bytetown, AB, could not stand that the candidates in the mayoral election campaign have been placing their electoral posters at all places at their whim. The city council has finally decided to build an electoral wall for placing the posters and introduce the following rules: 
  • Every candidate can place exactly one poster on the wall. 
  • All posters are of the same height equal to the height of the wall; the width of a poster can be any integer number of bytes (byte is the unit of length in Bytetown). 
  • The wall is divided into segments and the width of each segment is one byte. 
  • Each poster must completely cover a contiguous number of wall segments.

They have built a wall 10000000 bytes long (such that there is enough place for all candidates). When the electoral campaign was restarted, the candidates were placing their posters on the wall and their posters differed widely in width. Moreover, the candidates started placing their posters on wall segments already occupied by other posters. Everyone in Bytetown was curious whose posters will be visible (entirely or in part) on the last day before elections. 
Your task is to find the number of visible posters when all the posters are placed given the information about posters' size, their place and order of placement on the electoral wall. 

Input

The first line of input contains a number c giving the number of cases that follow. The first line of data for a single case contains number 1 <= n <= 10000. The subsequent n lines describe the posters in the order in which they were placed. The i-th line among the n lines contains two integer numbers li and ri which are the number of the wall segment occupied by the left end and the right end of the i-th poster, respectively. We know that for each 1 <= i <= n, 1 <= li <= ri <= 10000000. After the i-th poster is placed, it entirely covers all wall segments numbered li, li+1 ,... , ri.

Output

For each input data set print the number of visible posters after all the posters are placed. 

The picture below illustrates the case of the sample input. 

Sample Input

1
5
1 4
2 6
8 10
3 4
7 10

Sample Output

4

题目大意:

就是给你一张海报,在每个区间都会去张贴海报,并且后贴的会把之前贴的覆盖掉,让你求可以看到多少张海报。


刚开始就是认为线段树的区间合并问题,但是这个题困了我好久,就是因为需要离散化,之前也接触过离散化,但是不常用,所以看了下别人的代码,刚开始看怎么也看不懂,最后把每一步输出出来看看还是可以懂的。

原来的是(1,4),(2,6),(8,10),(3,4),(7,10),通过离散化之后把这些区间改边成(1,4),(2,5),(7,8),(3,4),(6,8)。

经过很长时间完成后的代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define lson l,mid,ri<<1
#define rson mid +1 ,r,ri<<1|1

int n,cnt;
const int maxn = 1e5+10;

struct Node{
    int l,r,n;
} a[maxn<<2];

struct node{
    int point,num;
} s[maxn<<2];

int map[maxn<<1][2],ans,vis[maxn<<1];

int cmp(node x,node y){
    return x.point<y.point;
}

void Build(int l,int r,int ri){
    a[ri].l = l;
    a[ri].r = r;
    a[ri].n = 0;
    if (l == r){
        return ;
    }
    int mid = (l+r)>>1;
    Build(lson);
    Build(rson);
}

void insert(int ri,int l,int r,int m){
    if(a[ri].l == l && a[ri].r == r){
        a[ri].n = m;
        return;
    }
    int mid = (a[ri].l+a[ri].r)>>1;
    if(a[ri].n>0){
        a[ri<<1].n = a[ri<<1|1].n = a[ri].n;
        a[ri].n = 0;
    }
    if(l>=a[ri<<1|1].l)
        insert(ri<<1|1,l,r,m);
    else if(r<=a[ri<<1].r)
        insert(ri<<1,l,r,m);
    else{
        insert(ri<<1,l,mid,m);
        insert(ri<<1|1,mid+1,r,m);
    }
}

void solve(int ri){
    if(a[ri].n){
        if(!vis[a[ri].n]){
            ans++;
            vis[a[ri].n] = 1;
        }
        return;
    }
    solve(ri<<1);
    solve(ri<<1|1);
    return;
}

int main(){
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d",&n);
        for(int i = 0; i < n; i++){
            scanf("%d%d",&map[i][0],&map[i][1]);
            s[i<<1].point = map[i][0];
            s[i<<1|1].point = map[i][1];
            s[i<<1].num = -(i+1);
            s[i<<1|1].num = i+1;
        }
//        for (int i = 0; i < 2*n; i++){
//            printf("%d %d %d\n",i,s[i].point,s[i].num);
//        }
        sort(s,s+2*n,cmp);
//        printf("\n");
//        for (int i = 0; i < 2*n; i++){
//            printf("%d %d %d\n",i,s[i].point,s[i].num);
//        }
        int temp = s[0].point,cnt = 1;
        for(int i = 0; i < 2*n; i++){
            if(temp != s[i].point){
                cnt++;
                temp = s[i].point;
            }
            if(s[i].num < 0)
                map[-s[i].num-1][0] = cnt;
            else
                map[s[i].num-1][1] = cnt;
        }
        Build(1,cnt,1);
        for(int i = 0; i < n; i++){
//            printf("%d %d\n",map[i][0],map[i][1]);
            insert(1,map[i][0],map[i][1],i+1);
        }
        memset(vis,0,sizeof(vis));
        ans = 0;
        solve(1);
        printf("%d\n",ans);
    }

    return 0;
}
多多努力,加油加油!

手把手教你编写智能合约(Smart Contract)

-
  • 1970年01月01日 08:00

poj2528 线段树+离散化

题意:n(n       求出最后还能看见多少张海报。 输入: 1 5 1 4 2 6 8 10 3 4 7 10 解法:离散化,如下面的例子(题目的样例),因为单位1是一个单位长度,...
  • Non_Cease
  • Non_Cease
  • 2012-03-22 22:32:10
  • 8449

线段树专题—POJ 3667 Hotel(区间合并模板)

题意:给一个n和m,表示n个房间,m次操作,操作类型有2种,一种把求连续未租出的房间数有d个的最小的最左边的房间号,另一个操作时把从x到x+d-1的房间号收回。 分析:这是一个区间合并的典型...
  • sin_XF
  • sin_XF
  • 2015-08-15 14:47:53
  • 913

POJ2528【线段树经典染色。】

来一点转的线段树精髓: 1、 线段树是二叉树,且必定是平衡二叉树,但不一定是完全二叉树。 2、 对于区间[a,b],令mid=(a+b)/2,则其左子树为[a,mid],右子树为[mid+1,b],当...
  • water__er
  • water__er
  • 2013-08-25 10:06:22
  • 2492

poj2528--Mayor's posters(线段树+离散化)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 41785 ...
  • u013015642
  • u013015642
  • 2014-08-08 19:50:02
  • 3641

POJ3667-Hotel-线段树区间合并(模板)

题目链接:http://poj.org/problem?id=3667 线段树真是牛逼啊,这么多的功能。。。 这是个线段树维护区间合并的问题;我们要维护一个区间的从左端点开始的最长区间,右端点的最...
  • wlxsq
  • wlxsq
  • 2015-08-06 09:52:08
  • 1012

POJ Hotel (线段树--区间合并[区间赋值])

题意: n间空房子, 操作1问你能否连续住x 个房子, 如果能 就输出最左边的编号。 如果不能输出0; 操作2 将给定的区间[x,y] 清空。 思路: 线段树区间合并。 像极了HDU 154...
  • aozil_yang
  • aozil_yang
  • 2017-06-20 22:06:18
  • 264

线段树+离散化操作(poj 2528)

模型建立: 本题的大致题意如下,我们先后向一块墙上贴n张海报,先贴的海报可能会被后贴的海报所覆盖,问在选举的最后一天还能看到几个人的海报。 很显然,我们记录下这个海报的左右端点并从后向前查询海报是...
  • aaron_1996
  • aaron_1996
  • 2015-10-26 23:48:00
  • 414

POJ 2528 Mayor's posters(线段树+离散化)

Mayor's posters Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 46857   Accepted:...
  • yeguxin
  • yeguxin
  • 2015-04-08 11:22:34
  • 496

【解题报告】POJ-2528 Mayor's posters 线段树+离散化

题目大意:有一面一千万长的墙,往墙上贴海报,海报的宽度给出。问最后一共能看到几面海报。 第一反应必然是线段树,但是一千万的线段树必然超内存,所以要离散化。因为我们其实只需要用到海报开始和结束的那两个...
  • Desico
  • Desico
  • 2017-05-18 21:26:45
  • 122
收藏助手
不良信息举报
您举报文章:poj 2528 线段树区间合并
举报原因:
原因补充:

(最多只允许输入30个字)