居然是一道图论题 毫无思路

我们对于每一次的融合操作 \((a,b)\) 建一个新点\(c\) 并向\(a,b\)连边 再将\(b\)瓶当前的位置赋成\(c\) 这样子我们就可以建成一个森林

现在枚举每一种反应\(M_i\) 看他在森林里是否存在\(lca\) 存在就相当于会在\(lca\)处发生反应 因为有反应的顺序 我们对\(lca\)排序后先做\(lca\)深度大的 深度相同就先做\(M\)的\(id\)小的 这样就满足题意了

我交了半天 居然是因为倍增数组写错了 真菜o(╥﹏╥)o

#include<bits/stdc++.h>
using namespace std;
#define FO(x) {freopen(#x".in","r",stdin);freopen(#x".out","w",stdout);}
#define pa pair<int,int>
#define mod 1000000007
#define ll long long
#define mk make_pair
#define pb push_back
#define fi fisrt
#define se second
#define cl(x) memset(x,0,sizeof x)
#ifdef Devil_Gary
#define bug(x) cout<<(#x)<<" "<<(x)<<endl
#define debug(...) fprintf(stderr, __VA_ARGS__)
#else
#define bug(x)
#define debug(...)
#endif
const int INF = 0x7fffffff;
const int N=2e5+5;
//*
char *TT,*mo,but[(1<<15)+2];
#define getchar() ((TT==mo&&(mo=(TT=but)+fread(but,1,1<<15,stdin),TT==mo))?-1:*TT++)//*/
inline int read(){
int x=0,rev=0,ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')rev=1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
return rev?-x:x;
}
struct Edge{
int v,nxt;
}e[N<<1];
struct data{
int u,v,f,dis,id;
}a[N*3];
ll ans;
int g[N],n,cnt,tot,m,K,head[N<<1],dep[N<<1],bin[23]={1},f[N<<1][22],pos[N];
void add(int u,int v){
e[++tot].v=v,e[tot].nxt=head[u],head[u]=tot;
}
bool cmp(const data&a,const data&b){
return a.dis==b.dis?a.id<b.id:a.dis>b.dis;
}
void dfs(int x){
for(int i=1;i<=19&&bin[i-1]<=dep[x];i++) f[x][i]=f[f[x][i-1]][i-1];
for(int i=head[x];i;i=e[i].nxt){
int j=e[i].v;
dep[j]=dep[x]+1,f[j][0]=x,dfs(j);
}
}
int LCA(int u,int v){
if(dep[u]<dep[v]) swap(u,v);
int ret=dep[u]-dep[v];
for(int i=19;~i;--i){
if(bin[i]&ret){
u=f[u][i];
}
}
if(u==v) return u;
for(int i=19;~i;i--){
if(f[u][i]!=f[v][i]){
u=f[u][i],v=f[v][i];
}
}
return f[u][0];
}
int main(){
#ifdef Devil_Gary
freopen("in.txt","r",stdin);
#endif
n=read(),m=read(),K=read();
for(int i=1;i<=20;i++) bin[i]=bin[i-1]<<1;
for(int i=1;i<=n;i++) g[i]=read(),pos[i]=i;
for(int i=1,x,y,z;i<=m;i++) {
x=read(),y=read(),z=n+i;
add(z,pos[x]),add(z,pos[y]),pos[y]=z;
}
for(int i=n+m;i;--i) if(!f[i][0]) dfs(i);
for(int i=1;i<=K;i++){
#define i cnt
a[++i].u=read(),a[i].v=read(),a[i].f=LCA(a[i].u,a[i].v),a[i].dis=dep[a[i].f],a[i].id=i;
#undef i
if(!a[cnt].f) --cnt;
}
sort(a+1,a+cnt+1,cmp);
for(int i=1,u,v,mn;i<=cnt;i++){
if(!a[i].f) continue;
u=a[i].u,v=a[i].v;
mn=min(g[u],g[v]);
g[u]-=mn,g[v]-=mn,ans+=mn;
}
printf("%lld\n",ans<<1);
}

BZOJ3712[PA2014]Fiolki 建图+倍增lca的更多相关文章

  1. BZOJ3712[PA2014]Fiolki——并查集重构树

    题目描述 化学家吉丽想要配置一种神奇的药水来拯救世界.吉丽有n种不同的液体物质,和n个药瓶(均从1到n编号).初始时,第i个瓶内装着g[i]克的第i种物质.吉丽需要执行一定的步骤来配置药水,第i个步骤 ...

  2. [bzoj3712][PA2014]Fiolki

    description 题面 data range \[ 0\le m<n\le 200000,0\le k\le 500000\] solution 之前本人一直煞笔地思考暴力是否可行 考虑按 ...

  3. 【BZOJ-3712】Fiolki LCA + 倍增 (idea题)

    3712: [PA2014]Fiolki Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 303  Solved: 67[Submit][Status] ...

  4. [bzoj3712][PA2014]Fiolki_倍增LCA

    Fiolki bzoj-3712 PA-2014 题目大意:题目链接. 注释:略. 想法: 神题! 我们建树:对于一次倾倒操作,我们弄一个新的大瓶子作为两个合并瓶子的父亲节点,与两个瓶子相连. 对于一 ...

  5. BZOJ 3712: [PA2014]Fiolki 倍增+想法

    3712: [PA2014]Fiolki Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 437  Solved: 115[Submit][Status ...

  6. BZOJ 4242 水壶(BFS建图+最小生成树+树上倍增)

    题意 JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有P个,编号为1...P. JOI君只能进入建筑 ...

  7. [十二省联考2019]字符串问题——后缀自动机+parent树优化建图+拓扑序DP+倍增

    题目链接: [十二省联考2019]字符串问题 首先考虑最暴力的做法就是对于每个$B$串存一下它是哪些$A$串的前缀,然后按每组支配关系连边,做一遍拓扑序DP即可. 但即使忽略判断前缀的时间,光是连边的 ...

  8. codevs 1036 商务旅行 (倍增LCA)

    /* 在我还不知道LCA之前 暴力跑的SPFA 70分 三个点TLE */ #include<iostream> #include<cstdio> #include<cs ...

  9. BFS+最小生成树+倍增+LCA【bzoj】4242 水壶

    [bzoj4242 水壶] Description JOI君所居住的IOI市以一年四季都十分炎热著称. IOI市是一个被分成纵H*横W块区域的长方形,每个区域都是建筑物.原野.墙壁之一.建筑物的区域有 ...

随机推荐

  1. Spark记录-Scala语句(运算符-if-for-while-try-模式匹配)

    Scala条件运算符 Scala条件运算符在下表中列出. 运算符 操作 描述 && 与 运算符左侧和右侧的值为true.仅当左侧为真时,右侧才被计算. || 或 左侧或右侧的至少一个值 ...

  2. li分两列显示

    只要控制了li的宽度,利用浮动就能实现<style type="text/css"> .my ul { width: 210px; } .my li { width: ...

  3. git 学习小记之记住https方式推送密码

    昨天刚刚学了点git基础操作,但是不幸的是Git@OSC给出公告说尽量使用 https 进行操作.可是在用 https 进行 push 时,都需要输入帐号和密码. 各种百度谷歌之后在Git@OSC官网 ...

  4. 将本地的mongodb迁移到阿里云

    首先在阿里云上安装mongodb,可以根据官方教程 https://docs.mongodb.com/manual/tutorial/install-mongodb-on-amazon/ 完成之后启动 ...

  5. Python3中的内置函数

    内置函数 我们一起来看看python里的内置函数.什么是内置函数?就是Python给你提供的,拿来直接用的函数,比如print,input等等.截止到python版本3.6.2,现在python一共为 ...

  6. Javascript - Vue - 请求

    本地增删查的一个例子 <div id="box">    <div class="panel panel-primary">       ...

  7. Linux内核中进程上下文、中断上下文、原子上下文、用户上下文的理解【转】

    转自:http://blog.csdn.net/laoliu_lcl/article/details/39972459 进程上下文和中断上下文是操作系统中很重要的两个概念,这两个概念在操作系统课程中不 ...

  8. 总结WCF开发中遇到的几个问题

    最近的项目,需要用到WCF,在以前的工作中,经常是将WCF托管在IIS中,主要有几下几个原因:      第一:部署非常方便,和部署一个站点没什么区别:      第二:不受防火墙的影响,因为一般服务 ...

  9. c++中的前置声明

    引用google c++编码规范: When you include a header file you introduce a dependency that will cause your cod ...

  10. 说一下PHP中die()和exit()区别

    PHP手册:die()Equivalent to exit(). 说明:die()和exit()都是中止脚本执行函数:其实exit和die这两个名字指向的是同一个函数,die()是exit()函数的别 ...