loj10131 暗的连锁
分析
首先我们知道如果在一棵树上加一条边一定会构成一个环,而删掉环上任意一条边都不改变连通性。我们把这一性质扩展到这个题上不难发现如果一条树边不在任意一个新边构成的环里则删掉这条边之后可以删掉任意一条新边,对方案数的贡献是m。而如果它只在一个新边构成的环中则要删除这条边和对应的新边,对方案数的贡献是1。而如果它在至少两个新边构成的环中则无论如何也不能将图分成两半,所以对方案数的贡献为0。在知道这些之后我们考虑如何维护一条边在几个由新边构成的环中,那我们自然考虑到了LCA,对于每一条新边将其LCA路径上的边的值都加1.所以我们只需要维护这个值就行了。据说可以用倍增+差分维护,但我并不会,我是用树剖维护的。我们考虑对于原来的树,除根节点外的每一个点入度一定为1,所以我们不在边上累加答案,而用这条边连接的两个点中深度较深的点来代表这条边,最后用2~n这几个点上的值便可以求出方案数。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<ctime>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
const int LOG = ;
vector<int>v[];
int ans,id[],col[],n,m;
int son[],siz[],cnt,dep[],fa[],acc[];
inline void dfs(int x,int la){
int maxn=;siz[x]=;
for(int i=;i<v[x].size();i++)
if(v[x][i]!=la){
fa[v[x][i]]=x;
dep[v[x][i]]=dep[x]+;
dfs(v[x][i],x);
siz[x]+=siz[v[x][i]];
if(siz[v[x][i]]>maxn){
maxn=siz[v[x][i]];
son[x]=v[x][i];
}
}
return;
}
inline void dfs2(int x,int ac){
id[x]=++cnt;
acc[x]=ac;
if(!son[x])return;
dfs2(son[x],ac);
for(int i=;i<v[x].size();i++)
if(v[x][i]!=fa[x]&&v[x][i]!=son[x])
dfs2(v[x][i],v[x][i]);
return;
}
inline void update(int le,int ri,int wh,int x,int y,int k){
if(x>y)return;
if(le>=x&&ri<=y){
col[wh]+=k;
return;
}
int mid=(le+ri)>>;
if(col[wh]){
col[wh<<]+=col[wh];
col[wh<<|]+=col[wh];
col[wh]=;
}
if(mid>=x)update(le,mid,wh<<,x,y,k);
if(mid<y)update(mid+,ri,wh<<|,x,y,k);
return;
}
inline int q(int le,int ri,int wh,int pl){
if(le==ri)return col[wh];
int mid=(le+ri)>>,ans;
if(col[wh]){
col[wh<<]+=col[wh];
col[wh<<|]+=col[wh];
col[wh]=;
}
if(mid>=pl)ans=q(le,mid,wh<<,pl);
else ans=q(mid+,ri,wh<<|,pl);
return ans;
}
inline void solve(int x,int y){
while(acc[x]!=acc[y]){
if(dep[acc[x]]<dep[acc[y]])swap(x,y);
update(,n,,id[acc[x]],id[x],);
x=fa[acc[x]];
}
if(id[x]>id[y])swap(x,y);
update(,n,,id[x]+,id[y],);
return;
}
int main(){
int i,j,k;
scanf("%d%d",&n,&m);
for(i=;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
v[x].push_back(y);
v[y].push_back(x);
}
fa[]=,dep[]=;
dfs(,);
dfs2(,);
for(i=;i<=m;i++){
int x,y;
scanf("%d%d",&x,&y);
solve(x,y);
}
for(i=;i<=n;i++){
int x=q(,n,,id[i]);
if(x==)ans+=m;
else if(x==)ans+=;
}
printf("%d\n",ans);
return ;
}
loj10131 暗的连锁的更多相关文章
- LOJ10131暗的连锁
题目描述 原题来自:POJ 3417 Dark 是一张无向图,图中有 N 个节点和两类边,一类边被称为主要边,而另一类被称为附加边.Dark 有 N–1 条主要边,并且 Dark 的任意两个节点之间都 ...
- LOJ #10131 「一本通 4.4 例 2」暗的连锁
LOJ #10131 「一本通 4.4 例 2」暗的连锁 给一棵 \(n\) 个点的树加上 \(m\) 条非树边 , 现在需要断开一条树边和一条非树边使得图不连通 , 求方案数 . $n \le 10 ...
- LOJ10131. 「一本通 4.4 例 2」暗的连锁【树上差分】
LINK solution 很简单的题 你就考虑实际上是对每一个边求出两端节点分别在两个子树里面的附加边的数量 然后这个值是0第二次随便切有m种方案,如果这个值是1第二次只有一种方案 如果这个值是2或 ...
- 倍增法求lca:暗的连锁
https://loj.ac/problem/10131 #include<bits/stdc++.h> using namespace std; struct node{ int to, ...
- LOJ P10131 暗的连锁 题解
每日一题 day27 打卡 Analysis 对于每条非树边 , 覆盖 x 到 LCA 和 y到 LCA 的边 , 即差分算出每个点和父亲的连边被覆盖了多少次 .被覆盖 0 次的边可以和 m 条非树边 ...
- POJ3417 Network暗的连锁 (树上差分)
树上的边差分,x++,y++,lca(x,y)-=2. m条边可以看做将树上的一部分边覆盖,就用差分,x=1,表示x与fa(x)之间的边被覆盖一次,m次处理后跑一遍dfs统计子树和,每个节点子树和va ...
- LuoguP3128 [USACO15DEC]最大流Max Flow (树上差分)
跟LOJ10131暗的连锁 相似,只是对于\(lca\)节点把它和父亲减一 #include <cstdio> #include <iostream> #include < ...
- loj题目总览
--DavidJing提供技术支持 现将今年7月份之前必须刷完的题目列举 完成度[23/34] [178/250] 第 1 章 贪心算法 √ [11/11] #10000 「一本通 1.1 例 1」活 ...
- CSU训练分类
√√第一部分 基础算法(#10023 除外) 第 1 章 贪心算法 √√#10000 「一本通 1.1 例 1」活动安排 √√#10001 「一本通 1.1 例 2」种树 √√#10002 「一本通 ...
随机推荐
- python-Django初体验
1.搭建Django开发环境 2.创建工程与应用 CentOS6.5环境下 Python 2.6 ipython 1.2.1 Django 1.6.5 pip install -y django == ...
- NHibernate常见错误汇总
NHibernateSample.Data.Test.QueryHQLFixture.WhereTest: NHibernate.Hql.Ast.ANTLR.QuerySyntaxException ...
- brew安装php和扩展
brew install homebrew/php/php56 --with-apache 报错: checking if the location of ZLIB install directory ...
- Rational Rose 2003 下载、破解及安装方法(图文)
方法一: 1. 安装Rational Rose2003时,在需选择安装项的时候,只选择Rational Rose EnterPrise Edition即可,不需选择其他项,之后选择“DeskTop I ...
- group by 和 聚合函数
1.在oracle中 select * from Table group by id 会报错. 会报不是group by 表达式.为什么一定不能是 * ,而必须是分组的列或者某个列的聚合函数. 在my ...
- [独孤九剑]Oracle知识点梳理(七)数据库常用对象之Cursor
本系列链接导航: [独孤九剑]Oracle知识点梳理(一)表空间.用户 [独孤九剑]Oracle知识点梳理(二)数据库的连接 [独孤九剑]Oracle知识点梳理(三)导入.导出 [独孤九剑]Oracl ...
- 算法之python创建链表实现cache
算法之python创建链表实现cache 本节内容 问题由来 解决思路 实现代码 总结 1. 问题由来 问题起因于朋友的一次面试题,面试公司直接给出两道题,要求四十八小时之内做出来,语言不限,做出来之 ...
- python基础准备
老男孩python全栈学习day1 第一讲python基础: 1.python起源:python的创始人为吉多·范罗苏姆(Guido van Rossum).1989年的圣诞节期间,吉多·范罗苏姆(中 ...
- java中List、Map、Set、Collection、Stack、Queue等的使用
java中这几个东西是比较常用的,虽然我用的不多,也正是因为用的不多,所以我一直搞不清楚他们之间的具体用法以及相互之间的关系,现在特单独作为一个东西来总结一下. 本文参考一下资料: 1.<jav ...
- Makefile 自动产生依赖 ***
代码如下: 其实这里主要是为每个C文件建立一个同名的后缀为.d.该文件的作用是使用gcc的-M属性来自动生成.o文件的头文件依赖关系. 第1,2,4都好理解. 第2行解释: 使用gcc -M 的属性将 ...