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

来源:互联网 发布:网络巡检报告 编辑:程序博客网 时间:2024/05/17 06:41

POJ 2528 Mayor's posters

区间覆盖的情况下染色,求可见的颜色种类

对区间端点离散化后,从1开始正常线段树了,最大范围是1W了。建图的点是离散后的区间端点值

查询的时候看这个颜色有没有出现过 ,没有就计数,哈希数组仍需要开到最大

离散化是将端点排序后映射到1~...用数组s保存端点原本的坐标值,离散化具体过程见->球逆序数的树状数组解法

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;#define INF 0x7FFFFFFF#define REP( i , n ) for ( int i = 0 ; i < n ; ++ i ) #define FOR( i , a , b ) for ( int i = a ; i <= b ; ++ i )#define CLR( a , x ) memset ( a , x , sizeof (a) )#define RE freopen("1.in","r",stdin)#define L(i) (i<<1)#define R(i) (i<<1|1)#define max(a,b) ((a)<(b)?(b):(a))#define NMAX 10000010#define maxn 10015int ans;int hash[NMAX];int arr[maxn];int vis[maxn];struct node{    int l,r;    int color;    int mid()    {        return (l+r)>>1;    }}tree[maxn<<3]; //改为2就REstruct Point{    int l,r;}p[maxn];int s[maxn<<1]; //够大void Pushdown(int u){    tree[L(u)].color = tree[u].color;    tree[R(u)].color = tree[u].color;    tree[u].color = 0;}void build(int u,int l,int r){    tree[u].l = l;    tree[u].r = r;    tree[u].color = 0;  //    if(l == r)        return;    int mid = tree[u].mid();    build(L(u),l,mid);    build(R(u),mid+1,r);}void add(int u,int l,int r,int val){    if(l <= tree[u].l && tree[u].r <= r)    {        tree[u].color = val;        return;    }    if(tree[u].color == val)        //颜色相同就没必要了        return;    if(tree[u].color)        Pushdown(u);    int mid = tree[u].mid();    if(r <= mid)        add(L(u),l,r,val);    else if(l > mid)        add(R(u),l,r,val);    else    {        add(L(u),l,mid,val);        add(R(u),mid+1,r,val);    }}void query(int u,int l,int r){    if(tree[u].color)                  {        if(!vis[tree[u].color]) //有颜色,再判断是否重复统计        {            ans++;            vis[tree[u].color] = 1;        }        return;         //不管是否重复都return    }    if(tree[u].color)        Pushdown(u);    if(tree[u].l == tree[u].r)      //叶结点就不用再下去了        return;    query(L(u),l,r);    query(R(u),l,r);}int main(){    //RE;    int n,q,a,b,c,t;    char ch;    while(scanf("%d",&t)!=EOF)    {        while(t--)        {            int k =0;            scanf("%d",&n);            CLR(vis,0);            CLR(hash,0);            FOR(i,0,n-1)            {                scanf("%d%d",&p[i].l,&p[i].r);                s[k++] = p[i].l;     //保存点,按区间端点保存                s[k++] = p[i].r;                 }            sort(s,s+k);                    int cnt = 0;            ans = 0;            FOR(i,0,k-1)            {           //hash保存结点编号,从1开始                if(!hash[s[i]])                    hash[s[i]] = ++cnt;            }            build(1,1,cnt);            int color = 1;            for(int i=0;i<n;i++)                add(1,hash[p[i].l],hash[p[i].r],color++);//            query(1,1,cnt);            printf("%d\n",ans);        }    }return 0;}


0 0