• [SDOI2011]染色


    一下午搭进去了。。

    最后发现少写了个pushup???

    有个关键的细节就是每次可合并两个区间的时候要判断一下ls的最左边的颜色和rs最右边的颜色一样不一样,一样就ans--

    然后就update和query的时候把链分成两节弄,否则很麻烦。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    using namespace std;
    const int N=100005;
    int n,dfn[N],top[N],siz[N],son[N],nxt[N<<1],to[N<<1],a[N],tim,dep[N],fa[N],head[N],ecnt,rnk[N];
    struct Seg{
        int l,r,lc,rc,cnt,lazy;
        Seg(){lazy=-1;}
    }t[N<<3];
    inline void add(int bg,int ed) {
        nxt[++ecnt]=head[bg];
        to[ecnt]=ed;
        head[bg]=ecnt;
    }
    void dfs(int x) {
        siz[x]=1;
        for(int i=head[x];i;i=nxt[i]) {
            if(to[i]!=fa[x]) {
                fa[to[i]]=x;
                dep[to[i]]=dep[x]+1;
                dfs(to[i]);
                siz[x]+=siz[to[i]];
                if(siz[to[i]]>siz[son[x]]) son[x]=to[i];
            }
        }
    }
    void dfs(int x,int Top) {
        top[x]=Top;dfn[x]=++tim;rnk[tim]=x;
        if(!son[x]) return;
        dfs(son[x],Top);
        for(int i=head[x];i;i=nxt[i]) {
            if(fa[x]!=to[i]&&to[i]!=son[x]) dfs(to[i],to[i]);
        }   
    }
    #define ls (cur<<1)
    #define rs (cur<<1|1)
    #define mid (l+r>>1)
    inline void pushup(int cur) {
        t[cur].lc=t[ls].lc;
        t[cur].rc=t[rs].rc;
        t[cur].cnt=t[ls].cnt+t[rs].cnt-(t[ls].rc==t[rs].lc);
    }
    void build(int l,int r,int cur) {
        t[cur].l=l,t[cur].r=r;t[cur].lazy=-1;
        if(l==r) {
            t[cur].lc=t[cur].rc=a[rnk[l]];t[cur].cnt=1;
            //cerr<<"BUILD:"<<rnk[l]<<' '<<t[cur].lc<<endl;
            return;
        }
        build(l,mid,ls);
        build(mid+1,r,rs);
        pushup(cur);
    }
    inline void pushdown(int cur) {
        if(t[cur].lazy!=-1) {
            t[ls].cnt=t[cur].cnt=1;t[cur].lc=t[cur].rc=t[ls].lc=t[ls].rc=t[ls].lazy=t[cur].lazy;
            t[rs].cnt=1;t[rs].lc=t[rs].rc=t[rs].lazy=t[cur].lazy;
            t[cur].lazy=-1;
        }
        return;
    }
    void modify(int ql,int qr,int l,int r,int cur,int c) {
        if(ql>qr) return;
        pushdown(cur);
        if(ql<=l&&r<=qr) {
            t[cur].cnt=1;t[cur].lazy=t[cur].lc=t[cur].rc=c;return;
        }
        int md=(l+r)>>1;
        if(ql<=mid) modify(ql,qr,l,mid,ls,c);
        if(mid<qr) modify(ql,qr,mid+1,r,rs,c);
        pushup(cur);
    }
    int query(int ql,int qr,int l,int r,int cur) {
        if(ql>qr) return 0;
        pushdown(cur);
        if(ql<=l&&r<=qr)  return t[cur].cnt;
        //int md=l+r>>1;
        if(qr<=mid) return query(ql,qr,l,mid,ls);
        else if(ql>mid) return query(ql,qr,mid+1,r,rs);
        else {
            int x=query(ql,qr,l,mid,ls),y=query(ql,qr,mid+1,r,rs);
            return x+y-(t[ls].rc==t[rs].lc);
        }
    }
    void _add(int x,int y,int c) {
        while(top[x]!=top[y]) {
            modify(dfn[top[x]],dfn[x],1,n,1,c);
            x=fa[top[x]];
        }
        modify(dfn[y],dfn[x],1,n,1,c);
    }
    int col(int cur,int x) {
        pushdown(cur);
        if(t[cur].l==t[cur].r) return t[cur].lc;
        int md=(t[cur].l+t[cur].r)>>1;
        if(x<=md) return col(ls,x);else return col(rs,x);
    }
    int query(int x,int y) {
        int ans=0;
        while(top[x]!=top[y]) {
            ans+=query(dfn[top[x]],dfn[x],1,n,1);
            if(col(1,dfn[fa[top[x]]])==col(1,dfn[top[x]])) ans--;
            x=fa[top[x]];
        }
        ans+=query(dfn[y],dfn[x],1,n,1);
        return ans;
    }
    int LCA(int x,int y) {
            while(top[x]!=top[y])
                (dep[top[x]]>=dep[top[y]])? x=fa[top[x]]:y=fa[top[y]];;
            return dep[x]<dep[y]?x:y;
    }
    int m;
    int main() {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),add(x,y),add(y,x);
        dfs(1);
        dfs(1,1);
        build(1,n,1);
        char opt[5];int a,b,c;
        while(m--) {
            scanf("%s",opt);
            if(opt[0]=='C') {
            scanf("%d%d%d",&a,&b,&c);
            int lca=LCA(a,b);
            _add(a,lca,c),_add(b,lca,c);
            }
            else if(opt[0]=='Q') {
                scanf("%d%d",&a,&b);
                int lca=LCA(a,b);
                printf("%d
    ",query(a,lca)+query(b,lca)-1);
            }
        }
        return 0;
    }
    染色
    我是咸鱼。转载博客请征得博主同意Orz
  • 相关阅读:
    (6).NET CORE微服务 Micro-Service ---- AOP框架
    (5).NET CORE微服务 Micro-Service ---- 熔断降级(Polly)
    (4).NET CORE微服务 Micro-Service ---- Consul服务发现和消费
    (3).NET CORE微服务 Micro-Service ---- Consul服务治理
    (2).NET CORE微服务 Micro-Service ---- .NetCore启动配置 和 .NetCoreWebApi
    (1).NET CORE微服务 Micro-Service ---- 什么是微服务架构,.netCore微服务选型
    ASP.NET Web Api 2 接口API文档美化之Swagger
    用Web api /Nancy 通过Owin Self Host简易实现一个 Http 服务器
    线程介绍
    C# 登陆验证码工具类VerifyCode
  • 原文地址:https://www.cnblogs.com/sdfzhsz/p/9716422.html
Copyright © 2020-2023  润新知