Codeforces 191 C Fools and Roads (树链剖分)
来源:互联网 发布:羊绒衫长款淘宝网商城 编辑:程序博客网 时间:2024/05/11 21:40
题目链接~~>
做题感悟:这题在做了HDU 5044后就感觉很简单了。
解题思路:
先树链剖分一下,把树剖分成链,因为最后全是询问,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 ;}
0 0
- Codeforces 191 C Fools and Roads (树链剖分)
- Codeforces 191C Fools and Roads(树链剖分)
- Codeforces-191C: Fools and Roads(LCA)
- Codeforces 192E Fools and Roads【树链剖分】
- Codeforce-191C-Fools and Roads (树链剖分 更新边权)
- Fools and Foolproof Roads CodeForces
- CodeForces 191C Fools and Roads 树上的前缀和 LCA
- CodeForces 题目191C. Fools and Roads(Link Cut Tree,边权加求边权值)
- codeforces 192E Fools and Roads
- Codeforces Round #121 (Div. 1) C. Fools and Roads 经典的lca前缀和问题
- Codeforces 362D Fools and Foolproof Roads 构造题
- [CF 191C]Fools and Roads[LCA Tarjan算法][LCA 与 RMQ问题的转化][LCA ST算法]
- Codeforces 362D Fools and Foolproof Roads【并查集+优先队列+思维】
- CodeForces 191CFools and Roads 树链剖分
- Codeforces 369D. Valera and Fools
- Codeforces Round #216_div2_D.Valera and Fools
- Codeforces Round #216_div2_D.Valera and Fools
- codeforces round 360 div2 C Chris and Roads
- UVA-10245 The Closest Pair Problem(最近点对问题)
- 南开,难以离开----南开78校庆贺文
- Codeforces Round #273 (Div. 2) --B Random Teams
- mac widget 安装下载网址
- string.h头文件的部分函数
- Codeforces 191 C Fools and Roads (树链剖分)
- nginx配置tomcat负载均衡+nginx服务器+apache后端服务器
- Windows下的Objective-C集成开发环境(IDE)的搭建
- js中的onclick事件传参
- Eclipse下使用Subversion(SVN工具)
- 拦截系统短信、电话
- iostat,iotop
- java.lang.NoSuchMethodError导致Tomcat无法启动的问题
- strcat第一个字符串末尾空格问题