zoukankan      html  css  js  c++  java
  • HDU6183 Color it 动态开点线段树

    网址:https://vjudge.net/problem/HDU-6183

    题意:

    给出以下操作:$“0”$代表清空所有颜色,$"1$ $x$ $y$ $c$$"$代表在坐标$(x,y)$涂上第$c$种颜色,$"2$ $x$ $y_1$ $y_2$$"$代表统计$x$轴上$[1,x]$和y轴上$[y_1,y_2]$的颜色数,一个点可以有多种颜色,$“3”$代表结束。数据保证$n,m leq 1e6,0 geq c leq 50,y_1 leq y_2$。

    题解:

    别问,问就开50棵线段树(MLE警告),开$50$棵动态开点的线段树,以$y$轴为结点,维护区间内的颜色的最小的横坐标值。查询时,横坐标的区间左边界已经确定,区间右边界为$x$,则小于等于$x$的才会被统计,则区间中的最小横坐标值决定该区间是否有颜色满足要求,然后依次查询$50$种颜色即可。(本题需要剪枝,如果在左子树搜到了,就不需要在右子树搜索,否则会TLE)。

    AC代码:

    #include <bits/stdc++.h>
    #pragma GCC optimize(3)
    using namespace std;
    const int MAXN=1000005;
    const int M=0x3f3f3f3f;
    
    struct segtree
    {
        struct node
        {
            int l,r,ls,rs,sum,minn;
            /*node()
            {
                l=r=ls=rs=sum=0;
                minn=M;
            }*/
        };
        node tr[MAXN*3];
        int rt[51];
        int tot=0;
        inline void init()
        {
            memset(rt,0,sizeof(rt));
            for(int i=0;i<MAXN*3;++i)
                tr[i].l=tr[i].r=tr[i].ls=tr[i].rs=tr[i].sum=0,tr[i].minn=M;
            tot=0;
        }
        inline void update(int &rt,int l,int r,int pos,int val)
        {
            if(!rt)
                rt=++tot;
            ++tr[rt].sum;
            tr[rt].l=l;
            tr[rt].r=r;
            tr[rt].minn=min(tr[rt].minn,val);
            if(l==r)
                return;
            int m=(l+r)>>1;
            if(pos<=m)
                update(tr[rt].ls,l,m,pos,val);
            else
                update(tr[rt].rs,m+1,r,pos,val);
            tr[rt].sum=tr[tr[rt].ls].sum+tr[tr[rt].rs].sum;
        }
        inline bool query(int l,int r,int rt,int lim)
        {
            if(!rt)
                return false;
            if(l<=tr[rt].l&&tr[rt].r<=r)
            {
                if(tr[rt].minn<=lim&&tr[rt].sum)
                    return true;
                else
                    return false;
            }
            int ans=0;
            int m=(tr[rt].l+tr[rt].r)>>1;
            if(l<=m&&!ans)
                ans+=query(l,r,tr[rt].ls,lim);
            if(r>m&&!ans)
                ans+=query(l,r,tr[rt].rs,lim);
            return ans;
        }
    };
    
    segtree tr;
    int main()
    {
        int a,b,c,d;
        while(scanf("%d",&a)&&a!=3)
        {
            if(a==0)
                tr.init();
            else if(a==1)
            {
                scanf("%d%d%d",&b,&c,&d);
                tr.update(tr.rt[d],1,1000000,c,b);
            }
            else if(a==2)
            {
                int ans=0;
                scanf("%d%d%d",&b,&c,&d);
                for(int i=0;i<=50;++i)
                    ans+=tr.query(c,d,tr.rt[i],b);
                printf("%d
    ",ans);
            }
        }
        return 0;
    }
    
  • 相关阅读:
    使用Redis实现分布式锁
    SpringBoot 定时任务的使用
    HTTP请求调试软件 Postman
    ElasticSearch的安装
    全文搜索 简介
    SpringBoot整合Redis
    Git 操作远程仓库(Github)
    Git的使用
    Git 简介、下载安装、配置
    Vue 商城的一些小demo(后台添加商品、前台购物车、本地存储的使用)
  • 原文地址:https://www.cnblogs.com/Aya-Uchida/p/11294655.html
Copyright © 2011-2022 走看看