主题链接~~>

做题情绪:做了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 (树链拆分)的更多相关文章

  1. Codeforces 191C Fools and Roads(树链拆分)

    题目链接:Codeforces 191C Fools and Roads 题目大意:给定一个N节点的数.然后有M次操作,每次从u移动到v.问说每条边被移动过的次数. 解题思路:树链剖分维护边,用一个数 ...

  2. hdu5044 Tree 树链拆分,点细分,刚,非递归版本

    hdu5044 Tree 树链拆分.点细分.刚,非递归版本 //#pragma warning (disable: 4786) //#pragma comment (linker, "/ST ...

  3. CF191C Fools and Roads - 树剖解法

    Codeforces Round #121 (Div. 1) C. Fools and Roads time limit per test :2 seconds memory limit per te ...

  4. 【Codeforces】【网络流】【树链剖分】【线段树】ALT (CodeForces - 786E)

    题意 现在有m个人,每一个人都特别喜欢狗.另外还有一棵n个节点的树. 现在每个人都想要从树上的某个节点走到另外一个节点,且满足要么这个人自带一条狗m,要么他经过的所有边h上都有一条狗. 2<=n ...

  5. Codeforces 856D - Masha and Cactus(树链剖分优化 dp)

    题面传送门 题意: 给你一棵 \(n\) 个顶点的树和 \(m\) 条带权值的附加边 你要选择一些附加边加入原树中使其成为一个仙人掌(每个点最多属于 \(1\) 个简单环) 求你选择的附加边权值之和的 ...

  6. Codeforces Round #425 (Div. 2) D 树链剖分 + 树状数组维护区间

    一看就知道 可以LCA判断做 也可以树链剖分拿头暴力 然而快速读入和线段树维护区间会T70 于是只能LCA? 线段树的常数不小 于是需要另外一种办法来进行区间加减和查询区间和 就是使用树状数组 这个题 ...

  7. Codeforces 696E ...Wait for it...(树链剖分)

    题目链接  ...Wait for it... 考虑树链剖分. 对于树上的每个点开一个set,记录当前该节点上所有的girls. 每个节点初始的权值为set中的最小值. 询问的时候每次在路径上寻找最小 ...

  8. HYSBZ 2243 染色 (树链拆分)

    主题链接~~> 做题情绪:这题思路好想.调试代码调试了好久.第一次写线段树区间合并. 解题思路: 树链剖分 + 线段树区间合并 线段树的端点记录左右区间的颜色.颜色数目.合并的时候就用区间合并的 ...

  9. poj 3237 Tree(树链拆分)

    题目链接:poj 3237 Tree 题目大意:给定一棵树,三种操作: CHANGE i v:将i节点权值变为v NEGATE a b:将ab路径上全部节点的权值变为相反数 QUERY a b:查询a ...

随机推荐

  1. Python Base64转码解码

    Python Base64 提供了好几种方法例如: encode, decode, encodestring, decodestring, b64encode, b64decode, standard ...

  2. Appium TestNg Maven Android Eclipse java简单启动实例

    环境准备 Eclipse + maven + appium + TestNg 确保已经在Eclipse 上面安装maven TestNg的插件 打开Eclipse,新建一个java项目,把项目转换成m ...

  3. 【问题解决】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: ./ ...

  4. BZOJ 1212 HNOI 2004 L语言 Trie树

    标题效果:给一些词.和几个句子,当且仅当句子可以切子可以翻译词典,这意味着该子将被翻译. 找到最长前缀长度可以被翻译. 思维:使用Trie树阵刷.你可以刷到最长的地方是最长的字符串可以翻译到的地方. ...

  5. Swift - 使用arc4random()、arc4random_uniform()取得随机数

    arc4random()这个全局函数会生成9位数的随机整数   1,下面是使用arc4random函数求一个1~100的随机数(包括1和100) 1 var temp:Int = Int(arc4ra ...

  6. fopen()功能

    1.2 文件输入和输出功能 键盘.显示器.打印机.磁盘驱动器和其他逻辑器件, 输入和输出可以通过文件管理方法可以完成. 最经常使用的编程是一个磁盘文件, 因此,这一部分主要是基于磁盘文件, 简介Tur ...

  7. 第四章 Spring与JDBC的整合

    这里选择的是mysql数据库. 4.1引入aop.tx的命名空间 为了事务配置的需要,我们引入aop.tx的命名空间 <?xml version="1.0" encoding ...

  8. RealThinClient学习(一)

    服务端代码: unit RtcHttpServer; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, ...

  9. C语言函数参数压栈顺序为何是从右到左?(从左向右的话,碰到printf的会陷入死循环)

    上学期学习了汇编语言,并在操作系统实验中使用了汇编+C语言混合编程,中间也了解了一些C语言与汇编语言的对应关系. 由于汇编语言是底层的编程语言,各种函数参数都要直接控制栈进行存取,在混合编程中,要用汇 ...

  10. mysql 高可用方案MHA介绍

    概述 MHA是一位日本MySQL大牛用Perl写的一套MySQL故障切换方案,来保证数据库系统的高可用.在宕机的时间内(通常10—30秒内),完成故障切换,部署MHA,可避免主从一致性问题,节约购买新 ...