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 ...
随机推荐
- 基础知识(9)- Swing用户界面组件
9.1 Swing和模型-视图-控制器设计模式 9.1.1 设计模式 9.1.2 模型-视图-控制器模式 9.1.3 Swing按钮的模型-视图-控制器分析 9.2 布局管理概述 9.2.1 ...
- 在VC资源文件中加入声音资源
本文介绍如何在VC资源文件中加入自己的声音资源,使自己的应用程序可以播放声音. 1.首先用文本编辑器(如记事本)打开资源文件(.rc文件) 在最后加入自己的声音资源,如下IDW WAVE " ...
- 判断指定进程是否为x64的方法(在ntdll判断某个x64函数是否存在)
BOOL IsWow64ProcessEx(HANDLE hProcess) { // 如果系统是x86的,那么进程就不可能有x64 bool isX86 = false; #ifndef _WIN6 ...
- uva 10602 Editor Nottoobad(排序)
题目连接:10602 Editor Nottoobad 题目大意:要输入n个单词,现在有三种操作, 1.输入一个字符,需要按下一次按键. 2.通过声控删除一个字符.3.通过声控复制一遍上面的单词.现 ...
- hao947 : Mybatis resultMap配置插入和主键自增返回 : 好947
映射配置文件 好947 <!-- type:映射实体类的数据类型 id:resultMap的唯一标识 --> <resultMap type="person" ...
- C语言scanf函数详解
函数名: scanf 功 能: 运行格式化输入 用 法: int scanf(char *format[,argument,...]); scanf()函数是通用终端格式化输入函数,它从标准输入设 ...
- 窗口显示于parent控件上(用到了ManualDock函数)
procedure TForm1.btn1Click(Sender: TObject); begin with TForm2.Create(self) do begin ManualDock(self ...
- sqlplus连接登录数据库时,出现 ORA-28009错误(转)
安装了oracle10g,打算用SQLPLUS 登录数据库进行操作.打开sqlplus后,可以看到要求输入用户名,口令和主机字符串.前面两个都知道,但是后一个却不明白,查了资料才知道是安装时的全局数据 ...
- java OOP及相关基础知识汇总(转)
OOP 对象有三个要素 behavior 接口是怎样的,有什么方法/field可以用? state 调用方法的时候,对象会有什么反应? 只有通过调用方法才能改变一个对象的state identity ...
- 14.4.3.3 Making the Buffer Pool Scan Resistant
14.4.3.3 Making the Buffer Pool Scan Resistant 让Buffer Pool 扫描 相比使用一个严格的LRU算法, InnoDB 使用一个技术来最小化数据的总 ...