zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    03、Jenkins相关概念
    02、Jenkins安装部署
    01、Jenkins简介
    10.ansible 利用playbook部署LAMP环境
    09.ansilbe利用playbook部署LNMP环境
    08.编译安装httpd
    python入门到放弃(五)-基本数据类型之list列表
    python入门到放弃(四)-基本数据类型之str字符串
    python入门到放弃(三)-基本数据类型之int整数和bool值
    CentOS7.5源码编译安装mysql5.7.29
  • 原文地址:https://www.cnblogs.com/thunder-110/p/10301420.html
Copyright © 2011-2022 走看看