Fork me on GitHub

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

题意:不讲了,线段树离散化的入门题。之所以贴出来只为吐槽几个地方:

1.最后统计颜色的时候,试了好几种方法都TLE,反正用vis就TLE,不知道别人的怎么行,最后没办法,学了网上一个机智的做法:用set记录ans个数,最后过了。

2.数据不对,离散化的时候如果排完序后相邻的元素值不相邻的话,是不能离散为相邻的两个元素的,比如数据:

3

1 10 

1 3

6 10

答案应该为3,而普通离散化后的线段变为了 [1,4], [1,2], [3,4],就是说[1,4]被其他两个线段给覆盖了,输出为2,这是不对的,但是POJ竟然可以过。一个字,水!

代码: (922ms飘过~)

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <map>
#include <set>
using namespace std;
#define N 10007
int L[N],R[N],line[2*N];
int tree[16*N],vis[N];
map<int,int> mp;
set<int> ans;

void build(int l,int r,int rt)
{
    tree[rt] = 0;
    if(l == r) return;
    int mid = (l+r)/2;
    build(l,mid,2*rt);
    build(mid+1,r,2*rt+1);
}

void pushdown(int rt,int col)
{
    if(tree[rt] != col && tree[rt] > 0)
    {
        tree[2*rt] = tree[2*rt+1] = tree[rt];
        tree[rt] = 0;
    }
}

void update(int l,int r,int aa,int bb,int col,int rt)
{
    if(aa <= l && bb >= r)
    {
        tree[rt] = col;
        return;
    }
    pushdown(rt,col);
    int mid = (l+r)/2;
    if(aa <= mid)
        update(l,mid,aa,bb,col,2*rt);
    if(bb > mid)
        update(mid+1,r,aa,bb,col,2*rt+1);
}

int query(int l,int r,int rt)    //Time Limit Exceeded
{
    if(tree[rt])
    {
        if(!vis[tree[rt]])
        {
            vis[tree[rt]] = 1;
            return 1;
        }
        return 0;
    }
    if(l == r)
        return 0;
    int mid = (l+r)/2;
    return query(l,mid,2*rt) + query(mid+1,r,2*rt+1);
}

int res;
void Q(int l,int r,int rt)     //Time Limit Exceeded
{
    if(tree[rt])
    {
        if(!vis[tree[rt]])
        {
            vis[tree[rt]] = 1;
            res++;
        }
        return;
    }
    if(l == r)
        return;
    int mid = (l+r)/2;
    Q(l,mid,2*rt);
    Q(mid+1,r,2*rt+1);
}

void SUM(int l,int r,int rt)     //Accepted
{
    if(tree[rt])
    {
        ans.insert(tree[rt]);
        return;
    }
    if(l == r)
        return;
    int mid = (l+r)/2;
    SUM(l,mid,2*rt);
    SUM(mid+1,r,2*rt+1);
}

int main()
{
    int t,n,i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        mp.clear();
        ans.clear();
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&L[i],&R[i]);
            line[2*i-1] = L[i];
            line[2*i] = R[i];
        }
        sort(line+1,line+2*n+1);
        int ind = unique(line+1,line+2*n+1)-line-1;
        int now = 0;
        mp[line[1]] = ++now;
        for(i=2;i<=ind;i++)
        {
            if(line[i] > line[i-1]+1)
                mp[line[i]] = now+2,now+=2;
            else if(line[i] == line[i-1] + 1)
                mp[line[i]] = ++now;
        }
        build(1,now,1);
        for(i=1;i<=n;i++)
            update(1,now,mp[L[i]],mp[R[i]],i,1);
        SUM(1,now,1);
        printf("%d\n",ans.size());
    }
    return 0;
}
View Code

 

posted @ 2014-08-21 21:06  whatbeg  阅读(255)  评论(0编辑  收藏  举报