【hiho1715】树的联通问题
题目大意:给定一棵 1~n 标号的树。Tree[L,R]表示最少需要选择的边的数量使得 L~R 号点两两连通。求:
\]
题解:
要求的是经过边的数量,可以考虑每条边对答案的贡献。
对于边 (u,v) ,定义一个特征序列 a[1...n],若 i 在以 u 为根的子树中,则 a[i]=1,否则 a[i]=0。发现若要求该边的贡献为 1,则选择的范围 a[l]-a[r] 中必须要既有 0 又有 1,这样才能跨过这条边,到达子树外面的节点。问题转化成了求对于树上每个节点的特征序列来说,既有 0 又有 1 的区间的个数和是多少。但是这个问题并不好求,可以转化为求特征序列中,只有 0 或 1 的区间个数,再用总共的区间个数减掉这些即可。因此,可以采用线段树来维护区间最长前后缀 0/1 的长度,区间合并的时候只需处理左区间的后缀和右区间的前缀即可完成。树上的问题还需要进行线段树合并来完成,时间复杂度为 \(O(nlogn)\)。
代码如下
#include <bits/stdc++.h>
#define pb push_back
using namespace std;
const int maxn=1e5+10;
typedef long long LL;
int n; LL ans;
vector<int> G[maxn];
struct node{
#define ls(o) t[o].lc
#define rs(o) t[o].rc
int lc,rc,lmx0,lmx1,rmx0,rmx1;
LL sum0,sum1;
}t[maxn*20];
int tot,rt[maxn];
inline void pushup(int o,int l,int r){
int mid=l+r>>1;
if(!ls(o))t[ls(o)].sum0=(LL)(mid-l+1)*(mid-l+2)/2,t[ls(o)].lmx0=t[ls(o)].rmx0=mid-l+1;
if(!rs(o))t[rs(o)].sum0=(LL)(r-mid)*(r-mid+1)/2,t[rs(o)].lmx0=t[rs(o)].rmx0=r-mid;
t[o].sum0=t[ls(o)].sum0+t[rs(o)].sum0+(LL)t[ls(o)].rmx0*t[rs(o)].lmx0;
t[o].sum1=t[ls(o)].sum1+t[rs(o)].sum1+(LL)t[ls(o)].rmx1*t[rs(o)].lmx1;
t[o].lmx0=t[ls(o)].lmx0==mid-l+1?t[ls(o)].lmx0+t[rs(o)].lmx0:t[ls(o)].lmx0;
t[o].lmx1=t[ls(o)].lmx1==mid-l+1?t[ls(o)].lmx1+t[rs(o)].lmx1:t[ls(o)].lmx1;
t[o].rmx0=t[rs(o)].rmx0==r-mid?t[rs(o)].rmx0+t[ls(o)].rmx0:t[rs(o)].rmx0;
t[o].rmx1=t[rs(o)].rmx1==r-mid?t[rs(o)].rmx1+t[ls(o)].rmx1:t[rs(o)].rmx1;
}
void insert(int &o,int l,int r,int pos){
if(!o)o=++tot;
if(l==r){t[o].lmx1=t[o].rmx1=t[o].sum1=1;return;}
int mid=l+r>>1;
if(pos<=mid)insert(ls(o),l,mid,pos);
else insert(rs(o),mid+1,r,pos);
pushup(o,l,r);
}
int merge(int x,int y,int l,int r){
if(!x||!y)return x+y;
if(l==r)return t[x].sum1?x:y;
int mid=l+r>>1;
ls(x)=merge(ls(x),ls(y),l,mid);
rs(x)=merge(rs(x),rs(y),mid+1,r);
return pushup(x,l,r),x;
}
void dfs(int u,int fa){
for(auto v:G[u]){
if(v==fa)continue;
dfs(v,u);
rt[u]=merge(rt[u],rt[v],1,n);
}
insert(rt[u],1,n,u);
LL ret=(LL)n*(n+1)/2-t[rt[u]].sum0-t[rt[u]].sum1;
if(u!=1)ans+=ret;
}
void read_and_parse(){
scanf("%d",&n);
for(int i=1;i<n;i++){
int x,y;
scanf("%d%d",&x,&y);
G[x].pb(y),G[y].pb(x);
}
}
void solve(){
dfs(1,0);
printf("%lld\n",ans);
}
int main(){
read_and_parse();
solve();
return 0;
}
【hiho1715】树的联通问题的更多相关文章
- 51 NOD 1325 两棵树的问题
Discription 对于 100% 的数据, N<=50. solution: 发现N比较小,所以我们可以花O(N^2)的代价枚举两颗树的联通块的LCA分别是哪个点,然后现在问题就变成了:选 ...
- P4383 [八省联考2018]林克卡特树 树形dp Wqs二分
LINK:林克卡特树 作为树形dp 这道题已经属于不容易的级别了. 套上了Wqs二分 (反而更简单了 大雾 容易想到还是对树进行联通情况的dp 然后最后结果总和为各个联通块内的直径. \(f_{i,j ...
- 题解西电OJ (Problem 1004 -亚特兰提斯)--最小生成树
Description 为了找寻沉睡的亚特兰提斯大陆,wm来到了大西洋上进行探险,找了半个月仍一无所获.然而在一次突袭而来的暴风雨后,wm的船莫名地驶入了一片未知的区域,发现了一个地图上未标记的岛屿, ...
- NOI前的考试日志
4.14 网络流专项测试 先看T1,不会,看T2,仙人掌???wtf??弃疗.看T3,貌似最可做了,然后开始刚,刚了30min无果,打了50分暴力,然后接着去看T1,把序列差分了一下,推了会式子,发现 ...
- kruskal重构树学习笔记
\(kruskal\) 重构树学习笔记 前言 \(8102IONCC\) 中考到了,本蒟蒻不会,所以学一下. 前置知识 \(kruskal\) 求最小(大)生成树,树上求 \(lca\). 算法详 ...
- 2015-2016 ACM-ICPC Northeastern European Regional Contest (NEERC 15)C - Cactus Jubilee
题意:给一颗仙人掌,要求移动一条边,不能放在原处,移动之后还是一颗仙人掌的方案数(仙人掌:无向图,每条边只在一个环中),等价于先删除一条边,然后加一条边 题解:对于一颗仙人掌,分成两种边,1:环边:环 ...
- Qtree4——动态点分治
题目描述 给出一棵边带权的节点数量为n的树,初始树上所有节点都是白色.有两种操作: C x,改变节点x的颜色,即白变黑,黑变白 A,询问树中最远的两个白色节点的距离,这两个白色节点可以重合(此时距离为 ...
- 【洛谷P1122】最大子树和
题目大意:给定一棵 N 个节点的无根树,点有点权,点权有正有负,求这棵树的联通块的最大权值之和是多少. 题解:设 \(dp[i]\) 表示以 i 为根节点的最大子树和,那么只要子树的 dp 值大于0, ...
- 【AC自动机】AC自动机
Definition & Solution AC自动机是一种多模式串的字符串匹配数据结构,核心在于利用 fail 指针在失配时将节点跳转到当前节点代表字符串的最长后缀子串. 首先对 模式串 建 ...
随机推荐
- 如何使用StarUML for Mac创建和修改元素
StarUML for Mac是一款UML软件建模器,支持快速编辑中的许多缩写,一次创建元素和关系,如子类,支持接口等.如何使用StarUML for Mac创建和修改元素?下面我们来介绍一下. 如何 ...
- (转)arcengine+c# 修改存储在文件地理数据库中的ITable类型的表格中的某一列数据,逐行修改。更新属性表、修改属性表某列的值。
作为一只菜鸟,研究了一个上午+一个下午,才把属性表的更新修改搞了出来,记录一下: 我的需求是: 已经在文件地理数据库中存放了一个ITable类型的表(不是要素类FeatureClass),注意不是要素 ...
- PTA(Basic Level)1042.字符统计
请编写程序,找出一段给定文字中出现最频繁的那个英文字母. 输入格式: 输入在一行中给出一个长度不超过 1000 的字符串.字符串由 ASCII 码表中任意可见字符及空格组成,至少包含 1 个英文字母, ...
- (5.3)mysql高可用系列——mysql复制之复制的参数
参考:https://www.iteye.com/blog/shift-alt-ctrl-2269539 详情 [1]参数 #[1.1]基本参数 bind-address=192.168.1.201 ...
- 【一道来自老师的题的题解】equip——奇妙的最短路
这道题真的第一眼完全想不到是最短路啊!!!!!!!! 感谢DR大佬讲解!!!!!90°鞠躬 =u= 暂时没有评测网址,(因为需要special judge)敬请期待 机房另一大佬JYY题解,可以对比参 ...
- 【pytorch】学习笔记(一)-张量
pytorch入门 什么是pytorch PyTorch 是一个基于 Python 的科学计算包,主要定位两类人群: NumPy 的替代品,可以利用 GPU 的性能进行计算. 深度学习研究平台拥有足够 ...
- Memcached安装 常用指令
Memcached 源码安装 # 安装依赖yum install -y gcc gcc-c++ automake autoconf make cmake libevent-devel.x86_64# ...
- Python中的xrld模块
一. 什么是xrld模块 python操作excel主要用到xlrd和xlwt这两个库,即xlrd是读excel,xlwt是写excel的库. 二. 使用介绍 . empty(空的), number, ...
- Codeforces 1221F. Choose a Square
传送门 对于某个点 $(x,y)$ ,不妨设 $x<y$ 因为如果 $x>y$ 直接按 $y=x$ 对称一下即可 当且仅当正方形左下角 $(a,a)$ 满足 $a<=x$,右上角 $ ...
- python网络爬虫(9)构建基础爬虫思路
目的意义 基础爬虫分5个模块,使用多个文件相互配合,实现一个相对完善的数据爬取方案,便于以后更完善的爬虫做准备. 这里目的是爬取200条百度百科信息,并生成一个html文件,存储爬取的站点,词条,解释 ...