POJ 2528 Mayor’s posters(离散化+成段更新)

来源:互联网 发布:免费域名加解析 编辑:程序博客网 时间:2024/04/30 19:49

题意:在墙上贴海报,海报可以互相覆盖,问最后可以看见几张海报

思路:这题数据范围很大,直接搞超时+超内存,需要离散化+线段树

此题re了N次,MAX越开越大,开始以为后台数据比实际范围大,其实是离散化+去重+加点后,MAX最多能到达3*MAX,然后建线段树最好要4*3*MAX大小。


#include <iostream>#include <algorithm>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <string>#include <vector>#include <set>#include <map>#include <queue>#include <stack>#include <climits>//形如INT_MAX一类的#define MAX 11111#define INF 0x7FFFFFFF#define REP(i,s,t) for(int i=(s);i<=(t);++i)#define mem(a,b) memset(a,b,sizeof(a))#define mp(a,b) make_pair(a,b)#define L(x) x<<1#define R(x) x<<1|1# define eps 1e-5//#pragma comment(linker, "/STACK:36777216") ///传说中的外挂using namespace std;struct node {    int l,r,mid,cover;} tree[MAX*12];int n;int l[MAX],r[MAX],x[4*MAX],xx[4*MAX],vis[MAX];int search(int v,int n) {    int ll = 1,rr = n,mid;    while(ll <= rr) {        mid = (ll + rr) >> 1;        if(v > xx[mid]) ll = mid + 1;        if(v == xx[mid]) return mid;        if(v < xx[mid]) rr = mid - 1;    }}void down(int x) {    if(tree[x].cover != -1) {//此条件很重要,否则就sb了        tree[L(x)].cover = tree[R(x)].cover = tree[x].cover;        tree[x].cover = -1;    }}void build(int l,int r,int num) {    tree[num].l = l;    tree[num].r = r;    tree[num].mid = (l+r) >> 1;    tree[num].cover = -1;    if(l == r)        return ;    build(l,tree[num].mid,L(num));    build(tree[num].mid + 1,r,R(num));}void update(int l,int r,int num,int color) {    if(l <= tree[num].l && r >= tree[num].r) {        tree[num].cover = color;        return ;    }    down(num);    if(r <= tree[num].mid) {        update(l,r,L(num),color);    } else if( l > tree[num].mid) {        update(l,r,R(num),color);    } else {        update(l,tree[num].mid,L(num),color);        update(tree[num].mid+1,r,R(num),color);    }}int query(int l,int r,int num) {    if(tree[num].cover != -1) {        if(vis[tree[num].cover] == 0) {            vis[tree[num].cover] = 1;            return 1;        }        return 0;    }    if(r <= tree[num].mid) {        return query(l,r,L(num));    } else if(l > tree[num].mid) {        return query(l,r,R(num));    } else {        return query(l,tree[num].mid,L(num)) + query(tree[num].mid+1,r,R(num));    }}void test(int n) {    for(int i=1; i<=3*n; i++) {        printf("l:%d r:%d cover:%d\n",tree[i].l,tree[i].r,tree[i].cover);    }}int main() {    int tt,i;    cin >> tt;    while(tt --) {        scanf("%d",&n);        int cnt = 0;        for(i=0; i<n; i++) {            scanf("%d%d",&l[i],&r[i]);            x[cnt++] = l[i];            x[cnt++] = r[i];        }        sort(x,x+cnt);        int m = 1;        for (i=1; i<cnt; i++) { //离散化去重            if (x[i] != x[i-1]) x[m ++] = x[i];        }        for (i=m-1; i>0; i --) { //加点解决边缘冲突            if (x[i] != x[i-1] + 1) x[m ++] = x[i-1] + 1;        }        sort(x,x+m);        int t = 0;        for(i=0; i<m; i++) {            xx[++t] = x[i];        }        build(1,t,1);        for(i=0; i<n; i++) {            update(search(l[i],t),search(r[i],t),1,i);        }        memset(vis,0,sizeof(vis));        cout << query(1,t,1) << endl;    }    return 0;}



原创粉丝点击