POJ 2528 Mayor's posters (line segment tree + discretization)

Topic link: http://poj.org/problem?id=2528

Solution: large scope, few points, consider discretization

1. Discretization maps 20,000 points of 1-10,000,000 to 1-20,000

The concrete steps are: counting all points - > sorting - > de-duplication - > mapping one by one.

The dis array is 1000w open, and the type is unsigned short (16 bits, enough size, and more space-saving)

 for (int i = 0;i<n;i++){
            scanf("%d %d",&l[i],&r[i]);
            mp[cnt++] = l[i];
            mp[cnt++] = r[i];
        }
        sort(mp,mp+cnt);
        cnt = unique(mp,mp+cnt)-mp;
        for (int i=0;i<cnt;i++)
            dis[mp[i]] = i+1;

2. Put the discrete intervals one by one into the segment tree for updating. The segment tree maintains the color of the segment. If tree[i]=-1 indicates that the segment has multiple colors, tree[i]=0 means no color.

There are probably tree arrays themselves as lazy arrays.

(2) push_up() is used to feedback the current node after the update of the child node, to ensure the correct value of the current node.

void push_up(int rt)
{
    if (tree[rt<<1]==-1 || tree[rt<<1|1]==-1) tree[rt] = -1;
    else {
        if (tree[rt<<1]==0) tree[rt] = tree[rt<<1|1];
        else if (tree[rt<<1|1]==0) tree[rt] = tree[rt<<1];
        else if (tree[rt<<1|1]!=tree[rt<<1]) tree[rt] = -1;
    }
}

void update(int L,int R,int x,int rt,int l,int r)
{
    //printf("rt=%d [%d,%d]\n",rt,l,r);
    if (L<=l && r<=R){
        tree[rt] = x;
        return ;
    }
    if (tree[rt]>0) tree[rt<<1] = tree[rt<<1|1] = tree[rt];
    mid;
    if (L<=m) update(L,R,x,lson);
    if (R>m) update(L,R,x,rson);
    push_up(rt);
}

3. dfs traverse the whole tree

When tree [rt]= - 1, the color of the child node is different, two child nodes are searched.

When tree[rt] = 0, the maintenance interval has no color, return directly

When tree [rt] > 0, there is a color. If the current color is not accessed, enter the answer and mark the access.

void dfs(int rt,int l,int r)
{
    //printf("tree=%d,[%d,%d]\n",tree[rt],l,r);
    if (tree[rt]>0){
        if (!vis[tree[rt]]) ans++;
        vis[tree[rt]] = true;
        return ;
    }
    if (!tree[rt]) return ;
    mid;
    if (tree[rt]==-1){
        dfs(lson);
        dfs(rson);
    }
}

Complete code:

#include<cstdio>
#include<algorithm>
#include<map>
#include<cstring>
#define lson rt<<1,l,m
#define rson rt<<1|1,m+1,r
#define mid int m = l+r>>1
#define debug(x) printf("Line %s----\n",#x)
using namespace std;

const int N = 2e4+5;

int tree[N<<2],ans;
bool vis[N];
int mp[N],l[N],r[N];
unsigned short dis[10000000+5];

void push_up(int rt)
{
    if (tree[rt<<1]==-1 || tree[rt<<1|1]==-1) tree[rt] = -1;
    else {
        if (tree[rt<<1]==0) tree[rt] = tree[rt<<1|1];
        else if (tree[rt<<1|1]==0) tree[rt] = tree[rt<<1];
        else if (tree[rt<<1|1]!=tree[rt<<1]) tree[rt] = -1;
    }
}

void update(int L,int R,int x,int rt,int l,int r)
{
    //printf("rt=%d [%d,%d]\n",rt,l,r);
    if (L<=l && r<=R){
        tree[rt] = x;
        return ;
    }
    if (tree[rt]>0) tree[rt<<1] = tree[rt<<1|1] = tree[rt];
    mid;
    if (L<=m) update(L,R,x,lson);
    if (R>m) update(L,R,x,rson);
    push_up(rt);
}

void dfs(int rt,int l,int r)
{
    //printf("tree=%d,[%d,%d]\n",tree[rt],l,r);
    if (tree[rt]>0){
        if (!vis[tree[rt]]) ans++;
        vis[tree[rt]] = true;
        return ;
    }
    if (!tree[rt]) return ;
    mid;
    if (tree[rt]==-1){
        dfs(lson);
        dfs(rson);
    }
}

int main()
{
    int t;
    scanf("%d",&t);
    while (t--){
        memset(tree,0,sizeof tree);
        memset(vis,0,sizeof vis);
        int n,cnt=0;
        scanf("%d",&n);
        for (int i = 0;i<n;i++){
            scanf("%d %d",&l[i],&r[i]);
            mp[cnt++] = l[i];
            mp[cnt++] = r[i];
        }
        sort(mp,mp+cnt);
        cnt = unique(mp,mp+cnt)-mp;
        for (int i=0;i<cnt;i++)
            dis[mp[i]] = i+1;
        for (int i = 0;i<n;i++){
            l[i] = dis[l[i]];
            r[i] = dis[r[i]];
            update(l[i],r[i],i+1,1,1,cnt);
        }

        ans = 0;
        dfs(1,1,cnt);
        printf("%d\n",ans);
    }
    return 0;
}



 

Posted by zed420 on Tue, 16 Apr 2019 18:03:33 -0700