zoukankan      html  css  js  c++  java
  • BZOJ 2243 染色

     呀这个还有代码编辑器啊。。我今天才发现。

    链剖水题。维护区间左端点和右端点的颜色。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #define maxv 200500
    #define maxe 200500
    #define maxn 805000
    using namespace std;
    int n,m,num[maxv],x,y,root=1,nume=0,tot=0,cnt=0,g[maxv];
    int dis[maxv],top[maxv],fath[maxv],size[maxv],son[maxv],w[maxv],fw[maxv];
    int ls[maxn],rs[maxn],lpos[maxn],rpos[maxn],lazy[maxn],sum[maxn];
    int a,b,c;
    bool vis[maxv],fff[maxv];
    char type[5];
    struct edge
    {
        int v,nxt;
    }e[maxe];
    void addedge(int u,int v)
    {
        e[++nume].v=v;
        e[nume].nxt=g[u];
        g[u]=nume;
    }
    void dfs1(int x)
    {
        son[x]=0;size[x]=1;
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if (v!=fath[x])
            {
                fath[v]=x;
                dis[v]=dis[x]+1;
                dfs1(v);
                if (size[v]>size[son[x]])
                    son[x]=v;
                size[x]=size[x]+size[v];
            }
        }
    }
    void dfs2(int x,int fa)
    {
        w[x]=++cnt;fw[cnt]=x;top[x]=fa;
        if (son[x]!=0) dfs2(son[x],fa);
        for (int i=g[x];i;i=e[i].nxt)
        {
            int v=e[i].v;
            if ((v!=fath[x]) && (v!=son[x]))
                dfs2(v,v);
        }
    }
    void build(int &now,int left,int right)
    {
        now=++tot;lpos[now]=0;rpos[now]=0;lazy[now]=-1;
        if (left==right)
        {
            int regis;
            regis=num[fw[left]];
            lpos[now]=regis;rpos[now]=regis;
            sum[now]=1;
            return;
        }
        int mid=(left+right)>>1;
        build(ls[now],left,mid);
        build(rs[now],mid+1,right);
        lpos[now]=lpos[ls[now]];rpos[now]=rpos[rs[now]];
        sum[now]=sum[ls[now]]+sum[rs[now]];
        if (rpos[ls[now]]==lpos[rs[now]]) sum[now]=sum[now]-1;
    }
    void pushdown(int now,int left,int right)
    {
        if (lazy[now]!=-1)
        {
            lazy[ls[now]]=lazy[now];lazy[rs[now]]=lazy[now];
            lpos[ls[now]]=lazy[now];lpos[rs[now]]=lazy[now];
            rpos[ls[now]]=lazy[now];rpos[rs[now]]=lazy[now];
            sum[ls[now]]=1;sum[rs[now]]=1;
            lazy[now]=-1;
        }
    }
    void modify(int now,int left,int right,int l,int r,int p)
    {
        pushdown(now,left,right);
        if ((left==l) && (right==r))
        {
            lazy[now]=p;sum[now]=1;
            lpos[now]=p;rpos[now]=p;
            return;
        }
        int mid=(left+right)>>1;
        if (r<=mid) modify(ls[now],left,mid,l,r,p);
        else if (l>=mid+1) modify(rs[now],mid+1,right,l,r,p);
        else 
        {
            modify(ls[now],left,mid,l,mid,p);
            modify(rs[now],mid+1,right,mid+1,r,p);
        }
        lpos[now]=lpos[ls[now]];rpos[now]=rpos[rs[now]];
        sum[now]=sum[ls[now]]+sum[rs[now]];
        if (rpos[ls[now]]==lpos[rs[now]]) sum[now]=sum[now]-1;
    }
    int ask(int now,int left,int right,int l,int r)
    {
        pushdown(now,left,right);
        if ((left==l) && (right==r))
            return sum[now];
        int mid=(left+right)>>1;
        if (r<=mid) return ask(ls[now],left,mid,l,r);
        else if (l>=mid+1) return ask(rs[now],mid+1,right,l,r);
        else
        {
            int regis=0;
            regis=ask(ls[now],left,mid,l,mid)+ask(rs[now],mid+1,right,mid+1,r);
            if (rpos[ls[now]]==lpos[rs[now]]) regis--;
            return regis;
        }
    }
    int find(int now,int left,int right,int p)
    {
        pushdown(now,left,right);
        if (left==p) return lpos[now];
        int mid=(left+right)>>1;
        if (p<=mid) return find(ls[now],left,mid,p);
        else return find(rs[now],mid+1,right,p);
    }
    void work1()
    {
        scanf("%d%d%d",&a,&b,&c);
        int f1=top[a],f2=top[b];
        while (f1!=f2)
        {
            if (dis[f1]<dis[f2]) {swap(f1,f2);swap(a,b);}
            modify(root,1,cnt,w[f1],w[a],c);
            a=fath[f1];f1=top[a];
        }
        if (dis[a]>dis[b]) swap(a,b);
        modify(root,1,cnt,w[a],w[b],c);
    }
    void work2()
    {
        int ans=0;
        scanf("%d%d",&a,&b);
        int f1=top[a],f2=top[b];
        while (f1!=f2)
        {
            if (dis[f1]<dis[f2]) {swap(f1,f2);swap(a,b);}
            ans=ans+ask(root,1,cnt,w[f1],w[a]);
            a=fath[f1];
            if (find(root,1,cnt,w[a])==find(root,1,cnt,w[f1]))
                ans--;
            f1=top[a];
        }
        if (dis[a]>dis[b]) swap(a,b);
        ans=ans+ask(root,1,cnt,w[a],w[b]);
        printf("%d
    ",ans);
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;i++)
            scanf("%d",&num[i]);
        for (int i=1;i<=n-1;i++)
        {
            scanf("%d%d",&x,&y);
            addedge(x,y);
            addedge(y,x);
        }
        dfs1(root);
        dfs2(root,root);
        build(root,1,cnt);
        for (int i=1;i<=m;i++)
        {
            scanf("%s",type);
            if (type[0]=='C') work1();
            else work2();
        }
        return 0;
    }
  • 相关阅读:
    LeetCode Subsets II
    LeetCode Rotate Image
    LeetCode Palidrome Number
    LeetCode Generate Parentheses
    LeetCode Maximum Subarray
    LeetCode Set Matrix Zeroes
    LeetCode Remove Nth Node From End of List
    Linux Loop设备 使用
    Linux 文件系统大小调整
    LeetCode N-Queens II
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5294010.html
Copyright © 2011-2022 走看看