Codeforces 191 C Fools and Roads (树链拆分)
做题情绪:做了HDU 5044后就感觉非常easy了。
解题思路:
先树链剖分一下,把树剖分成链,由于最后全是询问,so~能够线性操作。经过树链剖分后,就会形成很多链,可是每条边都有编号,相当于一个数组进行线性操作,这样。如果在 u ~ v 去都添加 1 。那么能够让 sum [ u ] += 1 ; sum [ v + 1 ] -= 1 ; 这里如果 v 的编号大。
最后的时候仅仅要从后往前遍历一次就能够了。得到全部的结果。明确这点后再加上树链剖分的思想就能够攻克了。
代码:
#include<iostream>
#include<sstream>
#include<map>
#include<cmath>
#include<fstream>
#include<queue>
#include<vector>
#include<sstream>
#include<cstring>
#include<cstdio>
#include<stack>
#include<bitset>
#include<ctime>
#include<string>
#include<cctype>
#include<iomanip>
#include<algorithm>
using namespace std ;
#define INT __int64
#define L(x) (x * 2)
#define R(x) (x * 2 + 1)
const int INF = 0x3f3f3f3f ;
const double esp = 0.0000000001 ;
const double PI = acos(-1.0) ;
const int mod = 1e9 + 7 ;
const int MY = 1400 + 5 ;
const int MX = 100000 + 5 ;
int n ,num ,idx ,m ;
int head[MX] ,sum[MX] ,ans[MX] ,P[MX] ,ti[MX] ,dep[MX] ,top[MX] ,siz[MX] ,son[MX] ,father[MX] ;
struct NODE
{
int u ,v ;
}e[MX] ;
struct node
{
int v ,next ;
}E[MX*2] ;
void addedge(int u ,int v)
{
E[num].v = v ; E[num].next = head[u] ; head[u] = num++ ;
E[num].v = u ; E[num].next = head[v] ; head[v] = num++ ;
}
void dfs_find(int u ,int fa)
{
dep[u] = dep[fa] + 1 ;
siz[u] = 1 ;
son[u] = 0 ;
father[u] = fa ;
for(int i = head[u] ;i != -1 ;i = E[i].next)
{
int v = E[i].v ;
if(v == fa) continue ;
dfs_find(v ,u) ;
siz[u] += siz[v] ;
if(siz[son[u]] < siz[v]) son[u] = v ;
}
}
void dfs_time(int u ,int fa)
{
ti[u] = idx++ ;
top[u] = fa ;
if(son[u]) dfs_time(son[u] ,top[u]) ;
for(int i = head[u] ;i != -1 ;i = E[i].next)
{
int v = E[i].v ;
if(v == father[u] || v == son[u]) continue ;
dfs_time(v ,v) ;
}
}
void LCA(int u ,int v)
{
while(top[u] != top[v])
{
if(dep[top[u]] < dep[top[v]])
swap(u ,v) ;
sum[ti[u]+1] -= 1 ;
sum[ti[top[u]]] += 1 ;
u = father[top[u]] ;
}
if(dep[u] > dep[v])
swap(u ,v) ;
if(u != v)
{
sum[ti[son[u]]] += 1 ;
sum[ti[v]+1] -= 1 ;
}
}
int main()
{
//freopen("input.txt" ,"r" ,stdin) ;
int u ,v ;
while(~scanf("%d" ,&n))
{
num = 0 ;
memset(head ,-1 ,sizeof(head)) ;
memset(sum ,0 ,sizeof(sum)) ;
for(int i = 1 ;i < n ; ++i)
{
scanf("%d%d" ,&e[i].u ,&e[i].v) ;
addedge(e[i].u ,e[i].v) ;
}
dep[1] = siz[0] = 0 ;
dfs_find(1 ,1) ;
idx = 1 ;
dfs_time(1 ,1) ;
scanf("%d" ,&m) ;
for(int i = 0 ;i < m ; ++i)
{
scanf("%d%d" ,&u ,&v) ;
LCA(u ,v) ;
}
for(int i = 1 ;i <= n ; ++i) // 第几条边
{
if(dep[e[i].u] < dep[e[i].v])
swap(e[i].u ,e[i].v) ;
P[ti[e[i].u]] = i ;
}
for(int i = 1 ;i <= n ; ++i) // 在剖分中的编号边的编号
{
sum[i] += sum[i-1] ;
ans[P[i]] = sum[i] ;
}
printf("%d" ,ans[1]) ;
for(int i = 2 ;i < n ; ++i)
printf(" %d" ,ans[i]) ;
puts("") ;
}
return 0 ;
}
版权声明:本文博客原创文章,博客,未经同意,不得转载。
Codeforces 191 C Fools and Roads (树链拆分)的更多相关文章
- Codeforces 191C Fools and Roads(树链拆分)
题目链接:Codeforces 191C Fools and Roads 题目大意:给定一个N节点的数.然后有M次操作,每次从u移动到v.问说每条边被移动过的次数. 解题思路:树链剖分维护边,用一个数 ...
- hdu5044 Tree 树链拆分,点细分,刚,非递归版本
hdu5044 Tree 树链拆分.点细分.刚,非递归版本 //#pragma warning (disable: 4786) //#pragma comment (linker, "/ST ...
- CF191C Fools and Roads - 树剖解法
Codeforces Round #121 (Div. 1) C. Fools and Roads time limit per test :2 seconds memory limit per te ...
- 【Codeforces】【网络流】【树链剖分】【线段树】ALT (CodeForces - 786E)
题意 现在有m个人,每一个人都特别喜欢狗.另外还有一棵n个节点的树. 现在每个人都想要从树上的某个节点走到另外一个节点,且满足要么这个人自带一条狗m,要么他经过的所有边h上都有一条狗. 2<=n ...
- Codeforces 856D - Masha and Cactus(树链剖分优化 dp)
题面传送门 题意: 给你一棵 \(n\) 个顶点的树和 \(m\) 条带权值的附加边 你要选择一些附加边加入原树中使其成为一个仙人掌(每个点最多属于 \(1\) 个简单环) 求你选择的附加边权值之和的 ...
- Codeforces Round #425 (Div. 2) D 树链剖分 + 树状数组维护区间
一看就知道 可以LCA判断做 也可以树链剖分拿头暴力 然而快速读入和线段树维护区间会T70 于是只能LCA? 线段树的常数不小 于是需要另外一种办法来进行区间加减和查询区间和 就是使用树状数组 这个题 ...
- Codeforces 696E ...Wait for it...(树链剖分)
题目链接 ...Wait for it... 考虑树链剖分. 对于树上的每个点开一个set,记录当前该节点上所有的girls. 每个节点初始的权值为set中的最小值. 询问的时候每次在路径上寻找最小 ...
- HYSBZ 2243 染色 (树链拆分)
主题链接~~> 做题情绪:这题思路好想.调试代码调试了好久.第一次写线段树区间合并. 解题思路: 树链剖分 + 线段树区间合并 线段树的端点记录左右区间的颜色.颜色数目.合并的时候就用区间合并的 ...
- poj 3237 Tree(树链拆分)
题目链接:poj 3237 Tree 题目大意:给定一棵树,三种操作: CHANGE i v:将i节点权值变为v NEGATE a b:将ab路径上全部节点的权值变为相反数 QUERY a b:查询a ...
随机推荐
- Python Base64转码解码
Python Base64 提供了好几种方法例如: encode, decode, encodestring, decodestring, b64encode, b64decode, standard ...
- Appium TestNg Maven Android Eclipse java简单启动实例
环境准备 Eclipse + maven + appium + TestNg 确保已经在Eclipse 上面安装maven TestNg的插件 打开Eclipse,新建一个java项目,把项目转换成m ...
- 【问题解决】syntax error: unexpected end of file或-bash: ./full_build.sh: /bin/bash^M: bad interpreter: No
在阅读的过程中有不论什么问题,欢迎一起交流 邮箱:1494713801@qq.com QQ:1494713801 运行一个脚本full_build.sh 时, 一直是提示我: -bash: ./ ...
- BZOJ 1212 HNOI 2004 L语言 Trie树
标题效果:给一些词.和几个句子,当且仅当句子可以切子可以翻译词典,这意味着该子将被翻译. 找到最长前缀长度可以被翻译. 思维:使用Trie树阵刷.你可以刷到最长的地方是最长的字符串可以翻译到的地方. ...
- Swift - 使用arc4random()、arc4random_uniform()取得随机数
arc4random()这个全局函数会生成9位数的随机整数 1,下面是使用arc4random函数求一个1~100的随机数(包括1和100) 1 var temp:Int = Int(arc4ra ...
- fopen()功能
1.2 文件输入和输出功能 键盘.显示器.打印机.磁盘驱动器和其他逻辑器件, 输入和输出可以通过文件管理方法可以完成. 最经常使用的编程是一个磁盘文件, 因此,这一部分主要是基于磁盘文件, 简介Tur ...
- 第四章 Spring与JDBC的整合
这里选择的是mysql数据库. 4.1引入aop.tx的命名空间 为了事务配置的需要,我们引入aop.tx的命名空间 <?xml version="1.0" encoding ...
- RealThinClient学习(一)
服务端代码: unit RtcHttpServer; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, ...
- C语言函数参数压栈顺序为何是从右到左?(从左向右的话,碰到printf的会陷入死循环)
上学期学习了汇编语言,并在操作系统实验中使用了汇编+C语言混合编程,中间也了解了一些C语言与汇编语言的对应关系. 由于汇编语言是底层的编程语言,各种函数参数都要直接控制栈进行存取,在混合编程中,要用汇 ...
- mysql 高可用方案MHA介绍
概述 MHA是一位日本MySQL大牛用Perl写的一套MySQL故障切换方案,来保证数据库系统的高可用.在宕机的时间内(通常10—30秒内),完成故障切换,部署MHA,可避免主从一致性问题,节约购买新 ...