• bzoj 3712: [PA2014]Fiolki


    Description

    化学家吉丽想要配置一种神奇的药水来拯救世界。
    吉丽有n种不同的液体物质,和n个药瓶(均从1到n编号)。初始时,第i个瓶内装着g[i]克的第i种物质。吉丽需要执行一定的步骤来配置药水,第i个步骤是将第a[i]个瓶子内的所有液体倒入第b[i]个瓶子,此后第a[i]个瓶子不会再被用到。瓶子的容量可以视作是无限的。
    吉丽知道某几对液体物质在一起时会发生反应产生沉淀,具体反应是1克c[i]物质和1克d[i]物质生成2克沉淀,一直进行直到某一反应物耗尽。生成的沉淀不会和任何物质反应。当有多于一对可以发生反应的物质在一起时,吉丽知道它们的反应顺序。每次倾倒完后,吉丽会等到反应结束后再执行下一步骤。
    吉丽想知道配置过程中总共产生多少沉淀。

    Input

    第一行三个整数n,m,k(0<=m<n<=200000,0<=k<=500000),分别表示药瓶的个数(即物质的种数),操作步数,可以发生的反应数量。
    第二行有n个整数g[1],g[2],…,g[n](1<=g[i]<=10^9),表示初始时每个瓶内物质的质量。
    接下来m行,每行两个整数a[i],b[i](1<=a[i],b[i]<=n,a[i]≠b[i]),表示第i个步骤。保证a[i]在以后的步骤中不再出现。
    接下来k行,每行是一对可以发生反应的物质c[i],d[i](1<=c[i],d[i]<=n,c[i]≠d[i]),按照反应的优先顺序给出。同一个反应不会重复出现。

    操作的过程可以看做一棵二叉树/森林,叶节点为药瓶,其余节点对应于操作,求lca可以找出一个反应发生的那次操作,然后在树上dfs一次模拟求出答案

    #include<cstdio>
    char buf[16000000],*ptr=buf-1;
    const int N=200007;
    int _(){
        int x=0,c=*++ptr;
        while(c<48)c=*++ptr;
        while(c>47)x=x*10+c-48,c=*++ptr;
        return x;
    }
    int n,m,k,g[N];
    int ch[N*2][2],fa[N*2],son[N*2],sz[N*2],dep[N*2],top[N*2],f[N*2],idp,v[500007][2];
    int es[500007],enx[500007],e0[500007],ep=2;
    long long ans=0;
    bool ed[N*2];
    void f1(int w,int pa){
        dep[w]=dep[fa[w]=pa]+1;
        sz[w]=1;
        if(w>n)
        for(int i=0;i<2;++i){
            int u=ch[w][i];
            f1(u,w);
            sz[w]+=sz[u];
            if(sz[u]>sz[son[w]])son[w]=u;
        }
    }
    void f2(int w,int tp){
        top[w]=tp;
        if(son[w])f2(son[w],tp);
        if(w>n)
        for(int i=0;i<2;++i){
            int u=ch[w][i];
            if(u!=son[w])f2(u,u);
        }
    }
    int min(int a,int b){return a<b?a:b;}
    void dec(int w){
        int x=v[w][0],y=v[w][1],z=min(g[x],g[y]);
        g[x]-=z,g[y]-=z,ans+=z;
    }
    void f3(int w){
        if(w>n)
        for(int i=0;i<2;++i)f3(ch[w][i]);
        for(int i=e0[w];i;i=enx[i])dec(es[i]);
    }
    int lca(int x,int y){
        int a=top[x],b=top[y];
        while(a!=b){
            if(dep[a]>dep[b])x=fa[a],a=top[x];
            else y=fa[b],b=top[y];
        }
        return dep[x]<dep[y]?x:y;
    }
    int get(int x){
        int a=x,c;
        while(x!=f[x])x=f[x];
        while(x!=f[a])c=f[a],f[a]=x,a=c;
        return x;
    }
    int main(){
        fread(buf,1,sizeof(buf),stdin);
        idp=n=_();m=_();k=_();
        for(int i=1;i<=n;++i)g[i]=_(),f[i]=i;
        for(int i=1,a,b;i<=m;++i){
            a=_(),b=_();
            ++idp;
            a=get(a),b=get(b);
            ch[idp][0]=a;
            ch[idp][1]=b;
            ed[a]=ed[b]=1;
            f[a]=f[b]=f[idp]=idp;
        }
        for(int i=1;i<=idp;++i)if(!ed[i])f1(i,0),f2(i,i);
        for(int i=1;i<=k;++i)v[i][0]=_(),v[i][1]=_();
        for(int i=k;i;--i){
            int c=lca(v[i][0],v[i][1]);
            if(c)es[ep]=i,enx[ep]=e0[c],e0[c]=ep++;
        }
        for(int i=1;i<=idp;++i)if(!ed[i])f3(i);
        printf("%lld
    ",ans<<1);
        return 0;
    }
  • 相关阅读:
    postgresql 添加触发器
    postgresql 操作
    postgresql 更新自增变量
    java8 stream api 文件流甚是牛逼
    fastjson妙用
    idea中springboot内置tomcat控制台中文乱码解决
    linux中开放某个端口
    idea中application.properties文件防止中文汉字自动转换成unicode编码解决办法
    使用vue开源项目vue-framework-wz遇到的问题以及解决方案
    rsync的使用
  • 原文地址:https://www.cnblogs.com/ccz181078/p/6339922.html
Copyright © 2020-2023  润新知