• Luogu P2486 [SDOI2011]染色


    P2486 [SDOI2011]染色

    卡了我五天的题目。。是一道树剖

    一直RE查出来是无限递归,(cur)下标爆炸了。。

    于是发现自己写的判断是边界重合。然后慌的改成了包含区间。我好菜啊。

    其实就是用线段树维护区间的左右边界颜色,上传的时候合并ans就好了。如果(leftson_{rightcolor}==rightson_{leftcolor})(cur_{ans}--)

    (什么sb题。。我为什么卡了五天)

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define MAXN 233333
    using namespace std;
    
    int n,m,tot=0,cnt=0;
    
    int w1[MAXN];
    
    struct qwq
    {
        int nex,to;
    }e[MAXN<<1];
    
    int dep[MAXN],son[MAXN],fa[MAXN],siz[MAXN],top[MAXN];
    
    int id[MAXN],h[MAXN];
    
    inline void add(int x,int y)
    {
        e[++tot].to=y;
        e[tot].nex=h[x];
        h[x]=tot;
    }
    
    inline void dfs_fir(int x,int f,int dept)
    {
        dep[x]=dept;
        fa[x]=f;
        siz[x]=1;
        int maxn=-1;
        for (int i=h[x],y;i;i=e[i].nex)
        {
            y=e[i].to;
            if (y==f) continue;
            dfs_fir(y,x,dept+1);
            siz[x]+=siz[y];
            if (siz[y]>maxn)
            {
                son[x]=y;
                maxn=siz[y];
            }
        }
    }
    inline void dfs_sec(int x,int ft)
    {
        id[x]=++cnt;;
        top[x]=ft;
        if (!son[x]) return;
        dfs_sec(son[x],ft);
        for (int i=h[x],y;i;i=e[i].nex)
        {
            y=e[i].to;
            if (y==fa[x]||y==son[x]) continue;
            dfs_sec(y,y);
        }
    }
    
    //segment_tree
    struct qq
    {
        int ans,tag,cl,cr;
    }f[MAXN<<2];
    #define leftson cur<<1
    #define rightson cur<<1|1
    #define mid ((l+r)>>1)
    #define push_down pd(cur)
    #define push_up pu(cur)
    inline void pd(int cur)
    {
        if (!f[cur].tag) return;
        f[leftson].ans=f[rightson].ans=1;
        f[leftson].tag=f[rightson].tag=f[cur].tag;
        f[leftson].cl=f[leftson].cr=f[cur].cl;
        f[rightson].cl=f[rightson].cr=f[cur].cl;
        f[cur].tag=0;
    }
    void pu(int cur)
    {
        f[cur].cr=f[rightson].cr;
        f[cur].ans=f[leftson].ans+f[rightson].ans;
        if (f[leftson].cr==f[rightson].cl)
        {
            f[cur].ans--;
        }
    }
    
    void change(int adl,int adr,int cur,int l,int r,int del)
    {
        if (adl<=l&&r<=adr)
        {
            f[cur].ans=f[cur].tag=1;
            f[cur].cl=f[cur].cr=del;
            return;
        }
        push_down;
        if (adr<=mid) change(adl,adr,leftson,l,mid,del);
        else if (adl>mid) change(adl,adr,rightson,mid+1,r,del);
        else
        {
            change(adl,adr,leftson,l,mid,del);
            change(adl,adr,rightson,mid+1,r,del);
        }
        push_up;
    }
    
    int bookl,bookr;
    int query(int cur,int l,int r,int al,int ar,int bl,int br)
    {
        if (l==bl) bookl=f[cur].cl;
        if (r==br) bookr=f[cur].cr;
    	if (al<=l&&r<=ar)
    	{
    		return f[cur].ans;
    	}
        push_down;
        if (ar<=mid) return /*printf("qmq........1:::%d %d %d %d %d %d %d
    ",leftson,l,mid,al,ar,bl,br),*/query(leftson,l,mid,al,ar,bl,br);
        else if (al>mid) return /*printf("qmq........2
    "),*/query(rightson,mid+1,r,al,ar,bl,br);
        else
        {
            int sum=query(leftson,l,mid,al,mid,bl,br)+query(rightson,mid+1,r,mid+1,ar,bl,br);
            if (f[leftson].cr==f[rightson].cl) sum--;
            return sum;
        }
        push_up;
    }
    
    
    //seg_tree.end
    
    
    void upd(int x,int y,int del)
    {
        while (top[x]!=top[y])
        {
            if (dep[top[x]]<dep[top[y]]) swap(x,y);
            change(id[top[x]],id[x],1,1,n,del);
            x=fa[top[x]];
        }
        if (dep[x]>dep[y]) swap(x,y);
        change(id[x],id[y],1,1,n,del);
    }
    
    int Query(int x,int y)
    {
        int ans=0;
        int s1=-1,s2=-1;
        while (top[x]!=top[y])
        {
            if (dep[top[x]]<dep[top[y]]) swap(x,y),swap(s1,s2);
            ans+=query(1,1,n,id[top[x]],id[x],id[top[x]],id[x]);
            if (bookr==s1) ans--;
            s1=bookl;
            x=fa[top[x]];
        }
        if (dep[x]<dep[y]) swap(x,y),swap(s1,s2);
        ans+=query(1,1,n,id[y],id[x],id[y],id[x]);
        if (bookl==s2) ans--;
        if (bookr==s1) ans--;
        return ans;
    }
    
    
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++)
        {
            scanf("%d",&w1[i]);
        }
        int x,y;
        for (int i=1;i<n;i++)
        {
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        dfs_fir(1,1,1);
        dfs_sec(1,1);
        for (int i=1;i<=n;i++)
        {
            change(id[i],id[i],1,1,n,w1[i]);
        }
        char c;
        int qwq,qvq,qxq;
        while (m--)
        {
            cin>>c;
            if (c=='C')
            {
                scanf("%d%d%d",&qwq,&qvq,&qxq);
                upd(qwq,qvq,qxq);
                continue;
            }
            scanf("%d%d",&qwq,&qvq);
            printf("%d
    ",Query(qwq,qvq));
        }
        return 0;
    }
    
  • 相关阅读:
    设计模式—适配器模式
    设计模式—策略模式 状态模式
    设计模式——装饰模式和代理模式
    C++常考算法
    ModelState.AddModelError使用
    Json
    ref与out
    三层与mvc
    新的方法(Set<T>)实现mvc的crud
    【程序45】
  • 原文地址:https://www.cnblogs.com/Kan-kiz/p/10980688.html
Copyright © 2020-2023  润新知