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: ...
随机推荐
- office word标题前面的编号变成黑色方块而不显示数字编号的解决方法
编写项目文档,文档的模板是office2003版的,文件后缀是.doc. 安照模板的格式把文档编写完成后保存.因为我是2010版的office,所以就保存成2010格式的文件后缀变成了.docx. 结 ...
- 使用BIND安装智能DNS服务器(二)---配置rndc远程控制
首先两个BIND DNS服务器要正常运行. 主DNS服务器IP:192.168.1.100 客户机DNS服务器IP:192.168.1.101 1 主DNS端配置: cd /etc/ 生成 ...
- Redis使用的相关问题
Redis用那些数据结构? 字符串类型String 字典Hash 列表List 集合Set 有序集合SortedSet HyperLogLog.Geo.Pub/Sub Redis Module.Blo ...
- vc++图像显示
显示资源中的图片 (1)从资源中装入位图 ● 定义位图对象数据成员CBitmap m_Bitmap; ● 调用CBitmap成员函数LoadBitmap(),如m_Bitmap.LoadBitmap( ...
- NLP入门(十)使用LSTM进行文本情感分析
情感分析简介 文本情感分析(Sentiment Analysis)是自然语言处理(NLP)方法中常见的应用,也是一个有趣的基本任务,尤其是以提炼文本情绪内容为目的的分类.它是对带有情感色彩的主观性 ...
- DIV文字水平垂直居中的方法
水平居中 text-align:center 垂直居中(vertical-align) vertical-align:middle; vertical-align时而没效果 然而真实使用的时候,我们会 ...
- include跟include_once 以及跟require的区别
include如果引入两个文件,都有一个相同的函数名,那么就会发生重定义的错误.使用include_once可以避免此错误,一般都_once用的比较多.应该根据实际情况需求include和_once的 ...
- Web项目开发介绍及实战项目介绍
引言 本系列课程我们将学些Golang语言中的Web开发框架Iris的相关知识和用法.通过本系列视频课程,大家能够从零到一经历一个完整项目的开发,并在课程中了解实战项目开发的流程和项目设涉及的各个模块 ...
- Solr 6.7学习笔记(07)-- More Like This
Solr中提供了MoreLikeThis的功能,用于查询相似的文档 .应用场景(个人理解):1. 你写的文章和别人文章相似度高的话,有一方是抄袭的可能性就很大.2. 查找相似的产品. MoreLike ...
- hdu1698(线段树区间替换模板)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1698 题意: 第一行输入 t 表 t 组测试数据, 对于每组测试数据, 第一行输入一个 n , 表示 ...