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 ...
随机推荐
- Linux虚拟机网络设置问题
使用的是VM 工作站15 和以前的不一样 没有什么虚拟机网络设置 :打开Edit->Virtual NetWork editor, 选中VMnet8,然后点击NAT Setting按钮,再点击D ...
- lnamp完整版[linux+apache2.4+php5.6.6+mysql5.6]
Lnamp环境安装实录 将采用的开源软件: Apache [WEB动态脚本服务器,做nginx的反向代理 8080端口] Tengine [WEB静态文件服务器 80端口] MySQL PHP .Ap ...
- 【转载】 原生js判断某个元素是否滚动到底部
document.querySelector('.content').addEventListener('scroll',function () { //读取内容区域的真实高度(滚动条高) // co ...
- 去掉html中的标签
//去掉html中的图片 String regEx_image = "(<img.*src\\s*=\\s*(.*?)[^>]*?>)"; Pattern p_s ...
- vue addRoutes路由动态加载
需求:增加权限控制,实现不同角色显示不同的路由导航 思路:每次登陆后请求接口返回当前角色路由 核心方法:vue-router2.2.0的addRoutes方法 + vuex 以下是我实现的获取菜单路由 ...
- LeetCode 1143 最长公共子序列
链接:https://leetcode-cn.com/problems/longest-common-subsequence 给定两个字符串 text1 和 text2,返回这两个字符串的最长公共子序 ...
- java上传大文件(局域网环境)
文件上传是最古老的互联网操作之一,20多年来几乎没有怎么变化,还是操作麻烦.缺乏交互.用户体验差. 一.前端代码 英国程序员Remy Sharp总结了这些新的接口 ,本文在他的基础之上,讨论在前端采用 ...
- Spring——简介
学习网站: [1]http://spring.io/ [2]http://projects.spring.io/spring-framework/ Spring是为解决企业应用开发的复杂性而创建的,是 ...
- Java——面向对象编程
在面向对象的编程中,不能再有第一步.第二步怎么做的概念. [对象和类]
- 3D Computer Grapihcs Using OpenGL - 02 QGLWidget
用红色来填充GLWidget窗口 修改MyGlWindow.h,添加两个函数,一个用来初始化OpengGL,一个用来绘制OpenGL #pragma once #include <QtOpenG ...