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;
    }
  • 相关阅读:
    RSA算法原理(二)
    RSA算法原理(一)
    Diffie-Hellman 算法
    1028:Ignatius and the Princess III
    1014:Uniform Generator
    1013:Digital Roots
    常见OJ评判结果对照表
    Django模板系统
    Django之视图
    Django之路由系统
  • 原文地址:https://www.cnblogs.com/ziliuziliu/p/5294010.html
Copyright © 2011-2022 走看看