poj 2528 Mayor's posters(动态线段树)

来源:互联网 发布:阿里云架设传奇教程 编辑:程序博客网 时间:2024/05/15 01:25

传送门:点击打开链接


题目大意:

给定一个 1 ~ 10000000 的区间,然后有N次操作(N <= 10000),第i次操作是将 l~r 区间覆盖为i。问最后一共有多少种有颜色。


解题思路:

一开始想到了离散化,但是想了一想感觉有点麻烦 然后就问专职搞数据结构的队友。然后他说了 动态线段树。思路如下:

定义一个ID。然后 根节点1表示掌管1-MAXN颜色的区间。然后每次都是动态的建树。当一个区间的左子区间还不存在时。建立它,并且记录下每个区间的左子区间和右子区间的ID.那么就可以搞了。

最后再用一个DFS 用SET来记录一共出现了多少种颜色。


注意:

当将一个区间的左子区间和右子区间被它更新之后时,一定要把他清零。

还有那个maxn。开始是未知的。


#include <set>#include <cstdio>using namespace std;#define maxn 2000000int lson[maxn],rson[maxn],color[maxn];int cnt,root;void build(){    cnt = 2;    root = 1;    lson[root] = 0;    rson[root] = 0;    color[root] = 0;}void pushdown(int id){    if(!lson[id])    {        lson[id] = cnt++;        lson[lson[id]] = 0;        rson[lson[id]] = 0;        color[lson[id]] = 0;    }    if(!rson[id])    {        rson[id] = cnt++;        lson[rson[id]] = 0;        rson[rson[id]] = 0;        color[rson[id]] = 0;    }    if(color[id])    {        color[lson[id]] = color[id];        color[rson[id]] = color[id];        color[id] = 0;    }}void op(int id,int ls,int rs,int l,int r,int c){    if(ls >= l && rs <= r)    {        color[id] = c;        return;    }    pushdown(id);    int mid = (ls+rs)>>1;    if(l <= mid) op(lson[id],ls,mid,l,r,c);    if(mid < r) op(rson[id],mid+1,rs,l,r,c);}set<int > ans;void dfs(int id){    if(color[id])    {        ans.insert(color[id]);        return;    }    if(lson[id]) dfs(lson[id]);    if(rson[id]) dfs(rson[id]);}int main(){    int T;    scanf("%d",&T);    for(int ks = 1;ks <= T;ks++)    {        int n;        scanf("%d",&n);        ans.clear();        build();        for(int i = 1;i <= n;i++)        {            int l,r;            scanf("%d %d",&l,&r);            op(root,1,10000000,l,r,i);        }        dfs(root);        printf("%d\n",ans.size());    }    return 0;}









0 0
原创粉丝点击