hdu 3966 树链剖分
2015-02-13 20:31
232 查看
不会树链剖分的可以看下面这个链接(本人写的,应该比较简洁易懂)
点击打开链接
就是模板题,没啥好说的,仔细一点一定能过...
本人水逼,wa了好几次...
点击打开链接
就是模板题,没啥好说的,仔细一点一定能过...
本人水逼,wa了好几次...
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #define N 50007 using namespace std; int head ,cc; struct Edge { int v,next; }e[N<<1]; void add ( int u , int v ) { e[cc].v = v; e[cc].next = head[u]; head[u] = cc++; } int top ,rank ,tid ,dep ,fa ,siz ,son ,a ,tim; void dfs1 ( int u , int father , int d ) { siz[u] = 1 , fa[u] = father , dep[u] = d; for ( int i = head[u] ; ~i ; i = e[i].next ) { int v = e[i].v; if ( v == father ) continue; dfs1 ( v , u , d+1 ); siz[u] += siz[v]; if ( son[u] == -1 || siz[son[u]] < siz[v] ) son[u] = v; } } void dfs2 ( int u , int tp ) { 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 Node { int l,r,sum,lazy; }tree[N<<2]; void push_up ( int u ) { tree[u].sum = tree[u<<1].sum + tree[u<<1|1].sum ; } void push_down ( int u ) { int lazy = tree[u].lazy; if ( lazy ) { tree[u<<1].sum += lazy*( tree[u<<1].r - tree[u<<1].l + 1 ); tree[u<<1|1].sum += lazy* ( tree[u<<1|1].r - tree[u<<1|1].l+1); tree[u<<1].lazy += lazy; tree[u<<1|1].lazy += lazy; tree[u].lazy = 0; } } void build ( int u , int left , int right ) { tree[u].l = left , tree[u].r = right; tree[u].lazy = 0; if ( left == right ) { tree[u].sum = a[rank[left]]; return; } int mid = left + right >> 1; build ( u<<1 , left , mid ); build ( u<<1|1 , mid+1 , right ); push_up ( u ); } void update ( int u , int left , int right , int v ) { int l = tree[u].l , r = tree[u].r; int mid = l + r >> 1; if ( left <= l && r <= right ) { tree[u].sum += (r-l+1)*v; tree[u].lazy += v; return; } push_down ( u ); if ( left <= mid && right >= l ) update ( u<<1 , left , right , v ); if ( left <= r && right > mid ) update ( u<<1|1, left , right , v ); push_up ( u ); } int query ( int u , int x ) { int l = tree[u].l , r = tree[u].r; if ( l == r ) return tree[u].sum; int mid = l + r >> 1; push_down ( u ); int ret = 0; if ( x >= l && x <= mid ) ret = query ( u<<1 , x ); else ret = query ( u<<1|1 , x ); push_up ( u ); return ret; } int get ( int x ) { return query ( 1 , tid[x] ); } void change ( int u , int v , int value ) { while ( top[u] != top[v] ) { if ( dep[top[u]] < dep[top[v]] ) swap ( u , v ); update ( 1 , tid[top[u]] , tid[u] , value ); u = fa[top[u]]; } if ( dep[u] > dep[v] ) swap ( u , v ); update ( 1 , tid[u] , tid[v] , value ); } int n,m,p; void init ( ) { cc = 0; tim = 0; memset ( head , -1 , sizeof ( head ) ); memset ( son , -1 , sizeof ( son ) ); } int main ( ) { while ( ~scanf ( "%d%d%d" , &n , &m , &p ) ) { for ( int i = 1 ; i <= n ; i++ ) scanf ( "%d" , &a[i] ); init ( ); int u , v , b; for ( int i = 1 ; i <= m ; i++ ) { scanf ( "%d%d" , &u , &v ); add ( u , v ); add ( v , u ); } dfs1 ( 1 , 0 , 0 ); dfs2 ( 1 , 1 ); build ( 1 , 1 , n ); char s[10]; for ( int i = 1 ; i <= p ; i++ ) { scanf ( "%s" , s ); if ( s[0] == 'I' ) { scanf ( "%d%d%d" , &u , &v , &b ); change ( u , v , b ); } if ( s[0] == 'D' ) { scanf ( "%d%d%d" , &u , &v , &b ); change ( u , v , -b ); } if ( s[0] == 'Q' ) { scanf ( "%d" , &b ); printf ( "%d\n" , get ( b ) ); } } } }
相关文章推荐
- hdu 3966(树链剖分)
- HDU 3966 RE 树链剖分 线段树 Aragorn's Story
- HDU 3966 树链剖分
- HDU 3966 Aragorn's Story 树链剖分
- [HDU] 3966 树状数组+启发式树链剖分
- hdu 3966 树链剖分
- HDU 3966 Aragorn's Story(树链剖分 (基于点权,查询单点值,修改路径的上的点权)模板题)
- HDU 3966 树链剖分
- Hdu 3966 Aragorn's Story (树链剖分)
- HDU 3966 & POJ 3237 & HYSBZ 2243 & HRBUST 2064 树链剖分
- hdu 3966 Aragorn's Story(树链剖分+树状数组)
- HDU 3966 Aragorn's Story(树链剖分)
- HDU 3966 Aragorn's Story (树链剖分)
- HDU 3966 Aragorn's Story(树链剖分)
- HDU 3966 Aragorn's Story 树链剖分+树状数组 或 树链剖分+线段树
- HDU 3966 [树链剖分]
- HDU 3966 Aragorn's Story 树链剖分
- hdu 3966 树链剖分 模板题
- HDU-3966-树链剖分
- HDU 3966 Aragorn's Story 树链剖分