zoukankan      html  css  js  c++  java
  • [BZOJ3712]Fiolki 重构树(并查集)

    3712: [PA2014]Fiolki

    Time Limit: 30 Sec  Memory Limit: 128 MB

    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]),按照反应的优先顺序给出。同一个反应不会重复出现。

    Output

    Sample Input

    3 2 1
    2 3 4
    1 2
    3 2
    2 3

    Sample Output

    6
     
     
     
    考试的时候,上来凭直觉觉得是并查集……
    此后第a[i]个瓶子不会再被用到.
    怎么看怎么是并查集嘛,然后……打了个链表的O(玄学)暴力,就开始想怎么优化查找的过程
    可是到考试结束也没想出来-_-最后只好交暴力了
    回了宿舍Troywardalao问我题面是什么(考试时候他都没看题,然而考完试他10min就淼掉了233)
    然后两个人想了10min就做出来了...(Torywar dalao为什么你想正解想得这么熟练啊)
    我们考虑这个倒药品的过程,很显然倒药品的顺序会产生影响.
    如果我们按照普通的并查集一样合并,会产生一系列问题,最大的问题就是不知道有哪些反应
    我们考虑每次合并新建节点并向他们连边(也就是重构树,参见http://www.cnblogs.com/LadyLex/p/7275821.html)
    这样,我们就把每一次合并拆开,并且独立考虑每次合并的过程
    接下来使用了类似离线的思想,我们首先处理一个计算lca的方式(tarjan,倍增随意了),然后考虑:
    对于每一对可以反应的物质,他们可能,也只可能在他们重构树上lca处反应
    既然这样,我们就可以把每个反应添加到他们的lca上
    随后,在扫一遍重构时新添加到点,也就是执行一遍倒药品的过程,并且处理可能发生的反应
    总的复杂度是O(m+nlogn+klogn+k),分别对应重构,ST表预处理,向lca添加反应,处理合并过程
    (ps:其实还是有一点遗憾,明明自己已经打过重构树的题了,考试时候却没想到.看来我对知识的掌握程度还没有到那么熟练的程度....联赛之前一定要把已经学的知识掌握扎实啊...)
    代码见下:
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <vector>
     5 using namespace std;
     6 const int N=200010,K=500010;
     7 typedef long long LL;
     8 LL sum;
     9 int n,m,k,w[N],fa[N<<1],bin[25];
    10 int e,adj[N<<1],cnt,f[N<<1][19],deep[N<<1];
    11 int find(int a){return fa[a]==a?a:fa[a]=find(fa[a]);}
    12 inline int min(int a,int b){return a<b?a:b;}
    13 struct data{int a,b;data(int x=0,int y=0){a=x,b=y;}}step[N];
    14 struct edge{int zhong,next;}s[N<<1];
    15 vector<data>re[N<<1];
    16 inline void add(int qi,int zhong)
    17     {s[++e].zhong=zhong;s[e].next=adj[qi];adj[qi]=e;}
    18 void dfs(int rt)
    19 {
    20     deep[rt]=deep[f[rt][0]]+1;
    21     for(int i=adj[rt];i;i=s[i].next)
    22         dfs(s[i].zhong);
    23 }
    24 inline void ST()
    25 {
    26     for(int i=1;i<=18;i++)
    27         for(int j=1;j<=cnt;j++)
    28             f[j][i]=f[f[j][i-1]][i-1];
    29 }
    30 inline int LCA(int a,int b)
    31 {
    32     if(deep[a]<deep[b])swap(a,b);
    33     int cha=deep[a]-deep[b];
    34     for(int j=18;~j;j--)
    35         if(cha&bin[j])a=f[a][j];
    36     if(a==b)return a;
    37     for(int j=18;~j;j--)
    38         if(f[a][j]!=f[b][j])a=f[a][j],b=f[b][j];
    39     return f[a][0];
    40 }
    41 int main()
    42 {
    43     bin[0]=1;for(int i=1;i<=20;i++)bin[i]=bin[i-1]<<1;
    44     int a,b,lca;scanf("%d%d%d",&n,&m,&k);cnt=n;
    45     for(int i=1;i<=n+m;i++)fa[i]=i;
    46     for(int i=1;i<=n;i++)scanf("%d",&w[i]);
    47     for(int i=1;i<=m;i++)
    48         scanf("%d%d",&step[i].a,&step[i].b),
    49         a=find(step[i].a),b=find(step[i].b),
    50         fa[a]=fa[b]=f[a][0]=f[b][0]=++cnt,
    51         add(cnt,a),add(cnt,b);
    52     ST();
    53     for(int i=1;i<=cnt;i++)
    54         if(!deep[i])dfs(find(i));
    55     for(int i=1;i<=k;i++)
    56     {
    57         scanf("%d%d",&a,&b);
    58         if(find(a)==find(b))
    59             lca=LCA(a,b),re[lca].push_back(data(a,b));
    60     }
    61     for(int i=n+1;i<=cnt;i++)
    62         for(int j=0,len=re[i].size();j<len;j++)
    63             a=min(w[re[i][j].a],w[re[i][j].b]),
    64             w[re[i][j].a]-=a,w[re[i][j].b]-=a,sum+=a;
    65     printf("%lld
    ",sum<<1);
    66 }
  • 相关阅读:
    Web API 强势入门指南
    毫秒必争,前端网页性能最佳实践
    Windbg Extension NetExt 使用指南 【3】 ---- 挖掘你想要的数据 Managed Heap
    Windbg Extension NetExt 使用指南 【2】 ---- NetExt 的基本命令介绍
    Windbg Extension NetExt 使用指南 【1】 ---- NetExt 介绍
    WCF : 修复 Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service 问题
    透过WinDBG的视角看String
    Microsoft Azure Web Sites应用与实践【4】—— Microsoft Azure网站的“后门”
    企业IT管理员IE11升级指南【17】—— F12 开发者工具
    WCF : 如何将NetTcpBinding寄宿在IIS7上
  • 原文地址:https://www.cnblogs.com/LadyLex/p/7470305.html
Copyright © 2011-2022 走看看