HDU6183 Color it 动态开点线段树

Posted aya-uchida

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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\n",ans);
        
    
    return 0;

 

以上是关于HDU6183 Color it 动态开点线段树的主要内容,如果未能解决你的问题,请参考以下文章

HDU6183 Color it (线段树动态开点)

HDU6183 Color it 动态开点线段树

HDU - 6183 Color it(动态开点线段树/树状数组套动态开点线段树)

HDU - 6183 动态开点线段树 || 令人绝望的线段树

HDU 6183 Color it cdq分治 + 线段树 + 状态压缩

HDU 6183 Color it