• Mayor's posters (离散化线段树+对lazy的理解)


    题目

    题意:

      n(n<=10000) 个人依次贴海报,给出每张海报所贴的范围 li,ri(1<=li<=ri<=10000000) 。求出最后还能看见多少张海报。

    思路:

      由于 li ri 都比较大,所以用离散化压缩一下空间,这里可以把所有的 li ri 都放在一个结构体数组 b[i] 中排序 再离散化。

      不同的人涂的不同颜色的海报,颜色分别用1-n标记。

      add数组就是Lazy数组。 1. 涂第一种颜色所有节点 rt  ,都使它的add[rt]为当前颜色,说明这个节点包含的左右区间的范围都被涂了这种颜色。   2. 第二种颜色来涂的时候,如果经过第一种已经涂过的节点rt,就把这个点的add[rt]传给add[rt<<1]和add[rt<<1|1],再把这个点add[rt]=0。如果第二种颜色的区间包括这个节点的区间,那么就涂成这个第二种颜色,如果没包括这个区间,就放着add[rt]=0了(如果我没理解错的话。。) ,继续遍历左右子区间,直到涂了颜色。 重复这样操作。

      最后的Built函数,是遍历一遍线段树中所有的节点,记录add[rt]有几个不同的值,就是答案。注意:如果找到一个节点已经涂了颜色,就说明这个节点包含的区间已经涂了这个颜色,就直接return,不用管这个节点的子节点了。

     

     我也是瞎写瞎猜的

    #include<iostream>
    #include<cstdio>
    #include <cctype>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<string>
    #include<cmath>
    #include<set>
    #include<vector>
    #include<stack>
    #include<queue>
    #include<map>
    using namespace std;
    #define ll long long
    #define mem(a,x) memset(a,x,sizeof(a))
    #define se second
    #define fi first
    const ll mod=1e9+7;
    const int INF= 0x3f3f3f3f;
    const int N=1e5+5;
    
    int add[N<<2];
    int n,m;
    int a[N<<1];
    int vis[N<<2];
    struct node
    {
        int v,p;
    }b[N<<1];
    int ans=0;
    
    bool cmp(node x,node y)
    {
        return x.v<y.v;
    }
    
    void push_down(int rt)
    {
        if(add[rt])
        {
            add[rt<<1]= add[rt];
            add[rt<<1|1]= add[rt];
            add[rt]=0;
        }
    }
    void Built(int l,int r,int rt)
    {
        if(add[rt])
        {
            if(!vis[add[rt]])
            {
                ans++;
                vis[add[rt]]=1;
            }
            return;
        }
        int m=l+r>>1;
        Built(l,m,rt<<1);
        Built(m+1,r,rt<<1|1);
    }
    
    void update(int x,int y,int c,int l,int r,int rt)
    {
        if(x<=l && r<=y)
        {
            add[rt]=c;
            return;
        }
        push_down(rt);
        int m=l+r>>1;
        if(x<=m) update(x,y,c,l,m,rt<<1);
        if(m<y) update(x,y,c,m+1,r,rt<<1|1);
    }
    
    int main()
    {
        int T,z;
        cin>>T;
        while(T--)
        {
            ans=0;
            mem(vis,0);
            //mem(add,0);
            
            scanf("%d",&n);
            for(int i=1;i<=n<<1;i++)
            {
                scanf("%d",&z);
                b[i].v=z; b[i].p=i;
            }
            sort(b+1,b+1+n*2,cmp);
            int cnt=0;
            for(int i=1;i<=n<<1;i++)
            {
                if(b[i].v != b[i-1].v)
                    cnt++;
                a[b[i].p]=cnt;
            }                    //离散化完毕 
            
            
            for(int i=1;i<=n<<1;i+=2)    
            {
                update(a[i], a[i+1], (i+1)/2, 1,cnt,1); //每张海报涂色不同 
            } 
            Built(1,n,1);
            cout<<ans<<endl;
        }
    }
    离散化+线段树+lazy
  • 相关阅读:
    iOS 面试题搜集
    iOS 常用第三方类库、完整APP示例
    iOS 键盘遮挡输入 解决办法
    iOS UIColor RGB HEX
    iOS APP性能优化
    iOS Swift 数组 交换元素的两种方法
    iOS CoreData primitive accessor
    iOS Start developing ios apps (OC) pdf
    iOS 传值方式
    iOS IB_DESIGNABLE IBInspectable @IBDesignable @IBInspectable 加速UI开发
  • 原文地址:https://www.cnblogs.com/thunder-110/p/10301420.html
Copyright © 2020-2023  润新知