hdu 5029 树链剖分+链表
来源:互联网 发布:java分销系统源码 编辑:程序博客网 时间:2024/06/11 08:56
因为是涂色问题,可以采用标记l 处+1和r+1处-1,把树状结构通过树链剖分转换成线性,利用线段树维护颜色中出现的最多的,利用二分查询能够找到出现次数最多且序号最小的颜色
#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#define MAX 200007using namespace std;int n,m,z;struct Edge{ int v,next,c;}e[MAX<<2];int head[MAX];int cc;void add ( int u , int v , int c = 0 ){ e[cc].v = v; e[cc].c = c; e[cc].next = head[u]; head[u] = cc++;}int dep[MAX],siz[MAX],fa[MAX],tid[MAX],son[MAX],top[MAX],rank[MAX],tim;void init ( ){ tim = 0; memset ( son , -1 , sizeof ( son ) );}void dfs1 ( int u = 1 , int p = 0 , int d = 0 ){ dep[u] = d , fa[u] = p , siz[u] = 1; for ( int i = head[u] ; ~i ; i = e[i].next ) { int v = e[i].v; if ( v == p ) continue; dfs1 ( v , u , d+1 ); siz[u] += siz[v]; if ( son[u]==-1 || siz[v] > siz[son[u]] ) son[u] = v; }}void dfs2 ( int u = 1, int tp = 1 ){ top[u] = tp ; tid[u] = ++tim; rank[tid[u]] = u; if ( son[u] == -1 ) return; dfs2 ( son[u] , tp ); for ( int i = head[u] ; ~i ; i = e[i].next ) { int v = e[i].v; if ( v == fa[u] || v == son[u] ) continue; dfs2 ( v , v ); }}struct Tree{ int l,r,mx;}tree[MAX<<2];void build ( int u , int l , int r ){ tree[u].l = l , tree[u].r = r; tree[u].mx = 0; if ( l == r ) return; int mid = l + r >> 1; build ( u<<1 , l , mid ); build ( u<<1|1 , mid+1 , r );}void push_up ( int u ){ tree[u].mx = max ( tree[u<<1].mx , tree[u<<1|1].mx );}void update ( int u , int x , int v ){ int l = tree[u].l , r = tree[u].r; if ( l == r ) { tree[u].mx += v; return; } int mid = l + r >> 1; if ( x > mid ) update ( u<<1|1 , x , v ); else update ( u<<1 , x , v ); push_up ( u );}int query ( int u ){ int l = tree[u].l , r = tree[u].r; if ( l == r ) return tree[u].l; if ( tree[u].mx == tree[u<<1].mx ) return query ( u<<1 ); else return query ( u<<1|1 );}void find ( int x , int y , int c ){ while ( top[x] != top[y] ) { if ( dep[top[x]] < dep[top[y]] ) swap ( x , y ); add ( tid[top[x]] , 1 , c ); add ( tid[x]+1 , -1 , c ); x = fa[top[x]]; } if ( dep[x] > dep[y] ) swap ( x , y ); add ( tid[x] , 1 , c ); add ( tid[y]+1 , -1 , c );} int ans[MAX];int main ( ){ while ( ~scanf ( "%d%d" , &n , &m ) , n+m ) { int l,r,c; memset ( head , -1 , sizeof ( head ) ); cc = 0; for ( int i = 1 ; i < n ; i++ ) { scanf ( "%d%d" , &l , &r ); add ( l , r ); add ( r , l ); } init ( ); dfs1 ( ); dfs2 ( ); memset ( head , -1 , sizeof ( head ) ); cc = 0; for ( int i = 0 ; i < m ; i++ ) { scanf ( "%d%d%d" , &l , &r , &c ); find ( l , r , c ); } build ( 1 , 0 , 100001 ); for ( int u = 1 ; u <= n ; u++ ) { for ( int i = head[u] ; ~i ; i = e[i].next ) update ( 1 , e[i].c , e[i].v ); ans[rank[u]] = query ( 1 ); } for ( int i = 1 ; i <= n ; i++ ) printf ( "%d\n" , ans[i] ); }}
0 0
- hdu 5029 树链剖分+链表
- HDU 5029 树链剖分
- hdu 5029树链剖分
- HDU 5029 树链剖分
- hdu 5029 Relief grain 树链剖分
- hdu 5029树链剖分+线段树
- hdu 5029 Relief grain 树链剖分
- hdu-5029
- Hdu 5029 Relief grain(树链剖分)
- hdu 5029 Relief grain (树链剖分+线段树)
- hdu 5029 Relief grain(树链剖分+线段树)
- HDU 5029 Relief grain(树链剖分)
- HDU 5029 Relief grain --树链剖分第一题
- HDU 5029Relief grain 树链剖分 好题
- HDU 5029Relief grain(树链剖分+线段树)
- HDU-3966 (树链剖分+线段树)
- HDU 5029 Relief grain
- hdu 5029 Relief grain
- tableview的两个获得重用cell方法的区别
- 关于STL中的map和hash_map (转)
- atitit。mssql sql server 转换mysql 及 分页sql ast的搭建
- UVA - 10825 Anagram and Multiplication 暴力
- c#网络编程常用特性之多线程
- hdu 5029 树链剖分+链表
- Dijkstra算法
- dlopen, dlsym等动态链接库函数解析
- C#中按引用传递与按值传递的区别
- kvo示例代码
- Android中获取应用程序(包)的信息-----PackageManager的使用(一)
- ref和out的用法及区别
- UVALive - 4394 String painter DP
- Android类装载器DexClassLoader的简单使用