Mayor's posters POJ2528

4 篇文章 0 订阅
2 篇文章 0 订阅

喜欢他的离散化方法,但是,看别人的解释

他的方法有问题就是

1

3

1 10

1 4

6 10

结果是2,但实际结果应该是3,解决方法得等我勤快起来才能写了.....

转自https://blog.csdn.net/u013569304/article/details/51276536 

 

 

 


//线段树D 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#include<stack>
#include<set>
#include<map>
#include<climits>

#define LL long long

using namespace std;

#define maxn 500010

#define lson o<<1, l, m
#define rson o<<1|1, m+1, r
#define GETM (l+r)>>1

using namespace std;

int _set[maxn*2];

bool vis[11000];

int fin_ans;

void pushdown(int o,int l,int r)
{
    if(_set[o]!=-1){

        _set[o*2]=_set[o];

        _set[o*2+1]=_set[o];

        _set[o]=-1;

    }

}

void updata(int o, int l, int r, int tl, int tr, int setv)
{

    if(tl<=l && r<=tr){
        _set[o] = setv;

        return ;
	}

    int m = GETM;

    pushdown(o, l, r);

    if(tl <= m)
        updata(lson, tl, tr, setv);

    if(m < tr)
        updata(rson, tl, tr, setv);

}

void query(int o, int l, int r) 
{
    if(_set[o] != -1) {
        if (!vis[_set[o]]) //pushdown时,回向下划分为两部分,此时会向这两部分递归找到海报所属范围,将其离散化(即赋值为setv),此时,set数组不同下表会有相同的值 
			fin_ans ++;
        vis[_set[o]] = true;

        return ;
    }

    if (l == r) return ;

    int m = GETM;

    query(lson);
    query(rson);
}

int arr_l[11000];
int arr_r[11000];
int temp[41000];

int main()
{

    int T;

    scanf("%d", &T);

    while(T--){

        int n;

        scanf("%d", &n);

        int i, pos=0;

        for(i=0; i<n; ++i){
            scanf("%d%d", &arr_l[i], &arr_r[i]);

            temp[pos++] = arr_l[i];
            temp[pos++] = arr_r[i];
        }

        int t=1;

		//先排序,后去重 
        sort(temp, temp+pos);
        
		int tt = unique(temp,temp+pos)-temp;//unique去重并返回去重后的数的个数 

        memset(_set, -1, sizeof(_set));
        memset(vis, false, sizeof(vis));

        for(i=0; i<n; ++i){
            int l = lower_bound(temp, temp+tt, arr_l[i])-temp;
            int r = lower_bound(temp, temp+tt, arr_r[i])-temp;

            updata(1, 0, tt-1, l, r, i);
        }

        fin_ans = 0;
        query(1, 0, tt-1);

        printf("%d\n", fin_ans);

    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值