BZOJ 3712: [PA2014]Fiolki 倍增+想法
3712: [PA2014]Fiolki
Time Limit: 30 Sec Memory Limit: 128 MB
Submit: 437 Solved: 115
[Submit][Status][Discuss]
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
2 3 4
1 2
3 2
2 3
Sample Output
HINT
Source
想法:
先看出树结构,然后分析:
一个反应最多进行一次,而且反应一定是在其LCA处反应。先不考虑中途其他反应,那么这个反应进行的时间是可以知道的。将这些反应按(反应时间,优先顺序)sort一下。模拟即可。
求反应时间就是求两个点最慢到LCA的时间,可以倍增。O(nlogn+klogn)
还有一种方法,按操作顺序,每操作一次建一个新容器用来装反应完的产物,例:x->y 这样: x->tmp y->tmp 然后y=tmp用来和后面的反应。
这样节点的深度与反应时间反相关,就可以不用倍增求,而用Tarjan求。从而O(n+k)
附上倍增代码
#include<cstdio>
#include<cmath>
#include<algorithm> typedef long long ll;
const int len(),lem(),INF(0x7fffffff);
int n,m,k,g[len+],a,b,logg;
int f[][len+],t[len+],depth[len+];
struct AB{int a,b,lca,id;}reaction[lem+];
struct Node{int nd,nx;}bot[len+];int tot,first[len+];
ll precipitation,ans; int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
bool cmp(AB A,AB B){return (A.lca<B.lca)||(A.lca==B.lca&&A.id<B.id);}
void add(int a,int b){bot[++tot]=(Node){b,first[a]};first[a]=tot;}
void swap(int &a,int &b){if(a==b)return;a^=b;b^=a;a^=b;}
template <class T>void read(T &x)
{
x=;int f=;char c=getchar();
while((c<''||c>'')&&c!='-')c=getchar(); if(c=='-')f=,c=getchar();
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
x=f?-x:x;
} void DFS(int x)
{
depth[x]++;
for(int v=first[x];v;v=bot[v].nx)
depth[bot[v].nd]=depth[x],DFS(bot[v].nd);
}
int lca(int a,int b)
{
if(depth[a]<depth[b])swap(a,b);
for(int k=depth[a]-depth[b]-,j=;k>;k>>=,j++)
if(k&)a=f[j][a];
if(f[][a]==b)return t[a];
if(depth[a]>depth[b]) a=f[][a];
for(int j=logg;f[][a]!=f[][b];j--)
if(f[j][a]!=f[j][b])a=f[j][a],b=f[j][b];
return max(t[a],t[b]);
}
int main()
{
// freopen("C.in","r",stdin);
// freopen("C.out","w",stdout);
read(n),read(m),read(k);
for(int i=;i<=n;i++)read(g[i]);
for(int i=;i<=m;i++)
{
read(a),read(b);
f[][a]=b; t[a]=i; add(b,a);
}
for(int i=;i<=n;i++)if(!f[][i])f[][i]=n+,add(n+,i),t[i]=INF;
DFS(n+);
logg=log2(n);
for(int j=;j<=logg;j++)
for(int i=;i<=n;i++)
f[j][i]=f[j-][ f[j-][i] ];
for(int i=;i<=k;i++)
{
read(a),read(b);
reaction[i].a=a;
reaction[i].b=b;
reaction[i].lca=lca(a,b);
// if(!reaction[i].lca)fprintf(stderr,"%d\n",i);
reaction[i].id=i;
}
std::sort(reaction+,reaction++k,cmp);
for(int i=;i<=k;i++)
if(reaction[i].lca!=INF)
{
precipitation=min(g[reaction[i].a],g[reaction[i].b]);
ans+=precipitation;
g[reaction[i].a]-=precipitation;
g[reaction[i].b]-=precipitation;
}else break;
printf("%lld",ans<<);
return ;
}
BZOJ 3712: [PA2014]Fiolki 倍增+想法的更多相关文章
- bzoj 3712: [PA2014]Fiolki
Description 化学家吉丽想要配置一种神奇的药水来拯救世界.吉丽有n种不同的液体物质,和n个药瓶(均从1到n编号).初始时,第i个瓶内装着g[i]克的第i种物质.吉丽需要执行一定的步骤来配置药 ...
- 【BZOJ】3712: [PA2014]Fiolki
http://www.lydsy.com/JudgeOnline/problem.php?id=3712 题意:n个瓶子,第i个瓶子里又g[i]克物质.m次操作,第i次操作把第a[i]个瓶子的东西全部 ...
- [PA2014]Fiolki
[PA2014]Fiolki 题目大意: 有\(n(n\le2\times10^5)\)种不同的液体物质和\(n\)个容量无限的药瓶.初始时,第\(i\)个瓶内装着\(g_i\)克第\(i\)种液体. ...
- BZOJ3712[PA2014]Fiolki 建图+倍增lca
居然是一道图论题 毫无思路 我们对于每一次的融合操作 $(a,b)$ 建一个新点$c$ 并向$a,b$连边 再将$b$瓶当前的位置赋成$c$ 这样子我们就可以建成一个森林 现在枚举每一种反应$M_i$ ...
- [bzoj3712][PA2014]Fiolki_倍增LCA
Fiolki bzoj-3712 PA-2014 题目大意:题目链接. 注释:略. 想法: 神题! 我们建树:对于一次倾倒操作,我们弄一个新的大瓶子作为两个合并瓶子的父亲节点,与两个瓶子相连. 对于一 ...
- BZOJ 3721: PA2014 Final Bazarek
3721: PA2014 Final Bazarek Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 645 Solved: 261[Submit][ ...
- BZOJ 3709: [PA2014]Bohater
3709: [PA2014]Bohater Time Limit: 5 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 1050 Solved: ...
- BZOJ 3732: Network 最小生成树 倍增
3732: Network 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=3732 Description 给你N个点的无向图 (1 &l ...
- 【贪心】bzoj 3709:[PA2014]Bohater
3709: [PA2014]Bohater Time Limit: 5 Sec Memory Limit: 128 MBSec Special JudgeSubmit: 653 Solved: ...
随机推荐
- Ubuntu下如何禁用IPv6
Ubuntu下如何禁用IPv6 2013-10-16 11:32:02 分类: HADOOP 分布式下的hadoop/hbase运行总出问题,zookeeper连接总是出问题,怀疑可能是ip ...
- storm事件管理器EventManager源码分析-event.clj
storm事件管理器定义在event.clj中,主要功能就是通过独立线程执行"事件处理函数".我们可以将"事件处理函数"添加到EventManager的阻塞队列 ...
- eos管理页面
调用此方法删除需要在po_module_processdef添加数据如下 默认情况下申请页面是有权限的 但是在此表加过之后 管理页面要打开拟稿页面还必须在 系统管理页面(xtgl.jsp ) 分 ...
- [51nod] 1289 大鱼吃小鱼 堆栈-模拟
有N条鱼每条鱼的位置及大小均不同,他们沿着X轴游动,有的向左,有的向右.游动的速度是一样的,两条鱼相遇大鱼会吃掉小鱼.从左到右给出每条鱼的大小和游动的方向(0表示向左,1表示向右).问足够长的时间之后 ...
- C#中的结构体要使用new来实例化吗?
声明结构的默认(无参数)构造函数是错误的.总是提供默认构造函数以将结构成员初始化为它们的默认值.在结构中初始化实例字段也是错误的. 如果使用 new 运算符创建结构对象,则会创建该结构对象,并调用适当 ...
- Hyperledger Fabric java chaincode 中文乱码问题
开发java chaincode过程中遇到一个中文乱码的问题.都是官方的demo,请求的sdk是用java写的,部署的chaincode有两种选择(不考虑node),一种go语言写的chaincode ...
- Python 获取页面title
#!/usr/bin/python #coding=utf- #urllib2是python自带的模块,在python3.x中被改为urllib.request import urllib.reque ...
- Nginx在Linux里安装 以及nginx实现负载均衡
Nginx 一.在Linux里安装软件 1. rpm命令 rpm: redhat package manager,红帽软件包管理套件 常用命令: 安装:rpm -ivh 软件包 i :安装模式 v : ...
- mac for Idea配置Tomcat
参考链接地址:http://blog.csdn.net/zsy3313422/article/details/52583091 IntelliJ使用 ##使用IntelliJ IDEA配置web项目时 ...
- SP14932 LCA - Lowest Common Ancestor
Description: 一棵树是一个简单无向图,图中任意两个节点仅被一条边连接,所有连通无环无向图都是一棵树.\(-Wikipedia\) 最近公共祖先(\(LCA\))是--(此处省去对\(LCA ...