hdu 5044 树链剖分+前缀和
来源:互联网 发布:万达电商 淘宝卖货 编辑:程序博客网 时间:2024/05/19 22:52
树链剖分裸题,主要是区间修改,最后一次查询,用前缀和来获取,复杂度o(1),时间卡得太死........#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>#include <cctype>#define MAX 100007using namespace std;typedef long long LL;void scan_num ( int &x ){ char c = getchar ( ); x = 0; while ( !isdigit( c ) ) c = getchar (); while ( isdigit(c) ) x = x*10 + c - 48, c = getchar ( );}void scan_str ( char s[] ){ char c = getchar (); int i = 0; while ( !isalnum( c ) ) c = getchar (); while ( isalnum ( c ) ) s[i++] = c, c = getchar (); s[i] = 0;}struct Edge{ int v , next , id;}e[MAX<<1];int head[MAX];int cc,tim;void add ( int u , int v , int id ){ e[cc].v = v; e[cc].id = id; e[cc].next = head[u]; head[u] = cc++;}int dep[MAX],siz[MAX],son[MAX],tid[MAX],fid[MAX],fa[MAX],top[MAX],loc[MAX];void dfs ( int u , int p , int d ){ son[u] = -1; fa[u] = p; siz[u] = 1; dep[u] = d; for ( int i = head[u]; ~i; i = e[i].next ) { int v = e[i].v; if ( v == p ) continue; loc[v] = e[i].id; dfs ( v , u , d+1 ); siz[u] += siz[v]; if ( son[u] == -1 || siz[son[u]] < siz[v] ) son[u] = v; }}void dfs ( int u , int tp ){ top[u] = tp; tid[u] = ++tim; fid[tid[u]] = u; if ( son[u] == -1 ) return; dfs ( son[u] , tp ); for ( int i = head[u]; ~i; i = e[i].next ) { int v = e[i].v; if ( v == son[u] || v == fa[u] ) continue; dfs ( v , v ); }} LL p[2][MAX<<1];void change ( int x , int y , int v , int f ){ while ( top[x] != top[y] ) { if ( dep[top[x]] < dep[top[y]] ) swap ( x , y ); if ( f ) p[1][tid[top[x]]*2-1] += v, p[1][tid[x]*2] -= v; else p[0][tid[top[x]]] += v, p[0][tid[x]+1] -= v; x = fa[top[x]]; } if ( dep[x] > dep[y] ) swap ( x , y ); if ( f ) p[1][tid[x]*2] += v, p[1][tid[y]*2] -= v; else p[0][tid[x]] += v, p[0][tid[y]+1] -= v;}int t,n,m,u,v,k;char s[15];LL ans0[MAX],ans1[MAX];int main ( ){ int c = 1; scan_num ( t ); while ( t-- ) { scan_num ( n ); scan_num ( m ); memset ( head , -1 , sizeof ( head ) ); memset ( p , 0 , sizeof ( p ) ); tim = cc = 0; for ( int i = 1 ; i < n ; i++ ) { scan_num ( u ); scan_num ( v ); add ( u , v , i ); add ( v , u , i ); } dfs ( 1 , -1 , 0 ); dfs ( 1 , 1 ); for ( int i = 0 ; i < m ; i++ ) { //scan_str ( s ); scanf ( "%s" , s ); scan_num ( u ); scan_num ( v ); scan_num ( k ); if ( s[3] == '1' ) change ( u , v , k , 0 ); else change ( u , v , k , 1 ); } p[0][0] = p[1][0] = 0; /* cout << "_________________________" << endl; for ( int i = 1 ; i <= 2*n ; i++ ) { cout << p[1][i] << " "; } cout << endl; cout << "_________________________" << endl;*/ for ( int i = 1 ; i <= n ; i++ ) p[0][i] += p[0][i-1]; for ( int i = 1 ; i <= n*2 ; i++ ) p[1][i] += p[1][i-1]; /*cout << "___________________________" << endl; for ( int i = 1 ; i <= 2*n ; i++ ) { cout << p[1][i] << " "; } cout << endl; cout << "____________________________" << endl;*/ /*for ( int i = 2 ; i <= n ; i++ ) { cout << loc[fid[i]] << " "; } cout << endl; cout << "_____________________________" << endl;*/ for ( int i = 1 ; i <= n ; i++ ) ans0[fid[i]] = p[0][i]; for ( int i = 2 ; i <= n ; i++ ) ans1[loc[fid[i]]] = p[1][2*i-1]; printf ( "Case #%d:\n" , c++ ); for ( int i = 1 ; i <= n ; i++ ) { if ( i != 1 ) printf ( " " ); printf ( "%I64d" , ans0[i] ); } puts (""); for ( int i = 1 ; i < n ; i++ ) { if ( i != 1 ) printf ( " " ); printf ( "%I64d" , ans1[i] ); } puts (""); } return 0;}
0 0
- hdu 5044 树链剖分+前缀和
- hdu 5044 树链剖分+前缀和
- hdu 5480(前缀和)
- HDU 6205 前缀和
- hdu 5084 前缀和预处理
- hdu 5163 前缀和+枚举
- hdu 5183 hash+前缀和
- hdu 1718 Rank(前缀和)
- HDU 5480:Conturbatio 前缀和
- 【前缀和】hdu 5480 Conturbatio
- hdu 5172(RMQ+前缀和)
- hdu 5327 Olympiad 前缀和
- HDU 5776 (sum 前缀和)
- HDU 5480 Conturbatio (前缀和)
- 前缀和 hdu 5480 (Conturbatio)
- hdu 1597 前缀和+lower_bound
- 【HDU 5327】Olympiad(前缀和)
- HDU 5327 Olymipad (前缀和)
- 1008. Elevator
- 【2013-5】 day2 一系列生成树问题
- mongodb 详解 error:10061 由于目标计算机积极拒绝,无法连接
- ORACLE 内置函数之 GREATEST 和 LEAST
- JAVA中util类里的map/set/list/vector之间的关系
- hdu 5044 树链剖分+前缀和
- C++ 大数模板
- 2015年3月10日学习心得
- Oracle中的NVL,NVL2,NULLIF,COALESCE函数
- Android内存管理
- Android开发,Log使用
- 如何避免JS变量命名冲突
- IP地址转换
- 教你怎样用unity3d发布一个Android的apk文件.绝对精细