Codeforces 191C (LCA+树上差分算法)
题面
传送门
题目大意:
给出一棵树,再给出k条树上的简单路径,求每条边被不同的路径覆盖了多少次
分析
解决这个问题的经典做法是树上差分算法
它的思想是把”区间”修改转化为左右端点的修改
在树上,每个节点初始权值为0,对于每条路径(x,y),我们令节点x的权值+1,节点y的权值-1,节点LCA(x,y)的权值-2
最后进行一次DFS,求出F[x]表示x为根的子树中各节点的权值之和,F[x]就是x与它的父节点之间的树边被覆盖的次数
用dfs序+ST表求LCA,时间复杂度O(nlog2n+k)" role="presentation" style="position: relative;">O(nlog2n+k)O(nlog2n+k)
代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#define maxn 100005
#define maxlog 32
using namespace std;
int n,k;
struct edge{
int from;
int to;
int next;
int index;
}E[maxn*2];
int head[maxn];
int size=0;
void add_edge(int u,int v,int id){
size++;
E[size].from=u;
E[size].to=v;
E[size].next=head[u];
E[size].index=id;
head[u]=size;
}
int dfn[maxn*2];
int used[maxn];
int fipos[maxn*2];
int deep[maxn*2];
int st[maxn*4][maxlog];
int cnt=0;
void get_dfn(int u,int d){
dfn[++cnt]=u;
if(fipos[u]==0){
fipos[u]=cnt;
deep[u]=cnt;
}
used[u]=1;
for(int i=head[u];i;i=E[i].next){
if(!used[E[i].to]){
get_dfn(E[i].to,d+1);
dfn[++cnt]=u;
}
}
}
void st_init(){
for(int i=1;i<=(n-1)*2;i++){
st[i][0]=dfn[i];
}
for(int j=1;(1<<j)<=(n-1)*2;j++){
for(int i=1;i<=(n-1)*2;i++){
if(deep[st[i][j-1]]<deep[st[i+(1<<(j-1))][j-1]]) st[i][j]=st[i][j-1];
else st[i][j]=st[i+(1<<(j-1))][j-1];
}
}
}
int st_query(int l,int r){
if(l>r) swap(l,r);
int k=log2(r-l+1);
if(deep[st[l][k]]<deep[st[r-(1<<k)+1][k]]) return st[l][k];
else return st[r-(1<<k)+1][k];
}
int lca(int x,int y){
int fx=fipos[x];
int fy=fipos[y];
return st_query(fx,fy);
}
int len[maxn];
int outlen[maxn];//按题目顺序输出
void get_len(int u){
used[u]=1;
for(int i=head[u];i;i=E[i].next){
if(!used[E[i].to]){
get_len(E[i].to);
len[u]+=len[E[i].to];
outlen[E[i].index]+=len[E[i].to];
}
}
}
int main(){
int u,v;
scanf("%d",&n);
for(int i=1;i<=n-1;i++){
scanf("%d %d",&u,&v);
add_edge(u,v,i);
add_edge(v,u,i);
}
get_dfn(1,0);
st_init();
scanf("%d",&k);
for(int i=1;i<=k;i++){
scanf("%d %d",&u,&v);
//树上差分算法
len[u]++;
len[v]++;
len[lca(u,v)]-=2;
}
memset(used,0,sizeof(used));
get_len(1);
for(int i=1;i<=n-1;i++) printf("%d ",outlen[i]);
}
Codeforces 191C (LCA+树上差分算法)的更多相关文章
- [BZOJ3307]:雨天的尾巴(LCA+树上差分+权值线段树)
题目传送门 题目描述: N个点,形成一个树状结构.有M次发放,每次选择两个点x,y对于x到y的路径上(含x,y)每个点发一袋Z类型的物品.完成所有发放后,每个点存放最多的是哪种物品. 输入格式: 第一 ...
- P1600 天天爱跑步[桶+LCA+树上差分]
题目描述 小c同学认为跑步非常有趣,于是决定制作一款叫做<天天爱跑步>的游戏.<天天爱跑步>是一个养成类游戏,需要玩家每天按时上线,完成打卡任务. 这个游戏的地图可以看作一一棵 ...
- [luogu P3128][USACO15DEC]Max Flow [LCA][树上差分]
题目描述 Farmer John has installed a new system of pipes to transport milk between the stalls in his b ...
- bzoj4326 树链剖分 + 线段树 // 二分 lca + 树上差分
https://www.lydsy.com/JudgeOnline/problem.php?id=4326 题意:N个点的树上给M条树链,问去掉一条边的权值之后所有树链长度和的最大值最小是多少. 首先 ...
- 2018.08.22 codves2370 小机房的树(lca+树上差分)
传送门 一道板子题. 直接树链剖分维护树上lca然后差分就行了. 代码: #include<bits/stdc++.h> #define N 50005 #define lc (p< ...
- 【洛谷】【lca+树上差分】P3258 [JLOI2014]松鼠的新家
[题目描述:] 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n(2 ≤ n ≤ 300000)个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真 ...
- [JLOI2014] 松鼠的新家 (lca/树上差分)
[JLOI2014]松鼠的新家 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在 ...
- LOJ2425 NOIP2015 运输计划 【二分+LCA+树上差分】*
LOJ2425 NOIP2015 运输计划 LINK 题意:给你一颗树,可以将任意一条边的权值变成0,然后求m条路径的长度的最小值 思路: 先二分最后的距离ans,然后我们把路程大于ans的所有路径拿 ...
- poj3417 Network——LCA+树上差分
题目:http://poj.org/problem?id=3417 根据一条边被几个环覆盖来判断能不能删.有几种情况等: 用树上差分,终点 s++,LCA s-=2,统计时计算子树s值的和即可: 用S ...
随机推荐
- POJ1523 SPF 单点故障
POJ1523 题意很简单,求删除割点后原先割点所在的无向连通图被分成了几个连通部分(原题说prevent at least one pair of available nodes from bein ...
- js的字符串是数字时过长的时候会被截断
JavaScript能表示并进行精确算术运算的整数范围为:正负2的53次方,也即从最小值-9007199254740992到最大值+9007199254740992之间的范围:对于超过这个范围的整数, ...
- Spring IOC 实现方式
Spring 中的 org.springframework.beans 包和 org.springframework.context 包构成了 Spring 框架 IoC 容器的基础. BeanFac ...
- Linux常用命令学习记录
兄弟连Linux培训 ,小编整理了常用的Linux学习命令: 1 cp 拷贝命令 参数:-p 文件属性一起拷贝 -r 拷贝文件夹 -d 软链信息等一起拷贝 -a 是-rdp的简写 2 find 文件查 ...
- 配置服务器(anaconda + jupyter + R)
总结一下整体的流程: 1. 服务器安装anaconda 首先清华镜像站下载anaconda3. 2. 将下载好的文件用scp命令传入服务器 注意:指定端口用-P命令 p大写 本机地址 用户名@服务器I ...
- Linq in not in\like not like
别人的博客 http://blog.163.com/lesheng@126/blog/static/357364652010102111051668/ using System.Data.Linq.S ...
- [BZOJ3236][AHOI2013]作业:树套树/莫队+分块
分析 第一问随便搞,直接说第二问. 令原数列为\(seq\),\(pre_i\)为\(seq_i\)这个值上一个出现的位置,于是可以简化询问条件为: \(l \leq i \leq r\) \(a \ ...
- 如何快速优雅的解决:ORA-02290: 违反检查约束条件 异常问题
在向oracle保存数据时,控制台报错如下: 很明显是保存时,该表的设计不允许某个字段非空导致的,但由于该表的数量较多,采用断点的方式有太过麻烦, 这里笔者采用 oracle 的客户端连接工具orac ...
- css内容过长显示省略号的几种解决方法
单行文本(方法一): 语法: text-overflow : clip | ellipsis 参数: clip : 不显示省略标记(...),而是简单的裁切 (clip这个参数是不常用的!) elli ...
- ubuntu18.04设置静态IP
ubuntu18与ubuntu14.16设置静态ip地方方法不同,很多人没去读更新文档的时候往往会设置静态ip地址不成功,下面是具体的设置方法 做之前一定要确认自己操作系统的版本,每个版本设置的方法有 ...