树链剖分...子树的树链剖分序必定是一段区间 , 先记录一下就好了

---------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
 
#define rep( i , n ) for( int i = 0 ; i < n ; i++ )
#define Rep( i , n ) for( int i = 1 ; i <= n ; ++i )
#define clr( x , c ) memset( x , c , sizeof( x ) )
#define REP( x ) for( edge* e = head[ x ] ; e ; e = e -> next )
 
using namespace std;
 
typedef long long ll;
 
const int maxn = 100000 + 5;
 
int n , seq[ maxn ];
 
struct edge {
int to;
edge* next;
};
 
edge* pt , EDGE[ maxn << 1 ];
edge* head[ maxn ];
 
void edge_init() {
pt = EDGE;
clr( head , 0 );
}
 
void _add( int u , int v ) {
pt -> to = v;
pt -> next = head[ u ];
head[ u ] = pt++;
}
 
#define add_edge( u , v ) _add( u , v ) , _add( v , u )
 
int top[ maxn ] , fa[ maxn ] , size[ maxn ] , dep[ maxn ] , son[ maxn ];
int id[ maxn ] , _id[ maxn ] , id_cnt = 0;
int LEFT[ maxn ] , RIGHT[ maxn ];
 
void dfs( int x ) {
size[ x ] = 1;
REP( x ) {
if( e -> to == fa[ x ] ) continue;
fa[ e -> to ] = x;
dep[ e -> to ] = dep[ x ] + 1;
dfs( e -> to );
size[ x ] += size[ e -> to ];
if( son[ x ] == -1 || size[ e -> to ] > size[ son[ x ] ] )
   son[ x ] = e -> to;
}
}
 
int TOP;
void DFS( int x ) {
LEFT[ x ] = id[ x ] = ++id_cnt;
_id[ id_cnt ] = x;
top[ x ] = TOP;
if( son[ x ] != -1 )
   DFS( son[ x ] );
REP( x ) if( id[ e -> to ] < 0 )
   DFS( TOP = e -> to );
RIGHT[ x ] = id_cnt;
}
 
void DFS_init() {
clr( id , -1 );
clr( son , -1 );
dfs( dep[ 0 ] = 0 );
DFS( TOP = 0 );
}
 
ll add[ maxn << 2 ] , sum[ maxn << 2 ];
 
int op , L , R , v;
 
#define mid( l , r ) ( l + r ) >> 1
#define L( x ) ( x << 1 )
#define R( x ) ( L( x ) ^ 1 )
 
void pushdown( int x , int l , int r ) {
if( add[ x ] ) {
   add[ L( x ) ] += add[ x ];
   add[ R( x ) ] += add[ x ];
   add[ x ] = 0;
}
}
void maintain( int x , int l , int r ) {
if( r > l ) {
sum[ x ] = sum[ L( x ) ] + sum[ R( x ) ] + add[ x ] * ( r - l + 1 );
} else {
   sum[ x ] += add[ x ];
   add[ x ] = 0;
}
}
 
void update( int x , int l , int r ) {
if( L <= l && r <= R ) {
add[ x ] += v;
} else {
pushdown( x , l , r );
int m = mid( l , r );
L <= m ? update( L( x ) , l , m ) : maintain( L( x ) , l , m );
m < R ? update( R( x ) , m + 1 , r ) : maintain( R( x ) , m + 1 , r );
}
maintain( x , l , r );
}
void U( int l , int r ) {
L = l , R = r;
update( 1 , 1 , n );
}
 
ll query( int x , int l , int r ) {
if( L <= l && r <= R )
return sum[ x ];
int m = mid( l , r );
pushdown( x , l , r );
maintain( L( x ) , l , m );
maintain( R( x ) , m + 1 , r );
return ( L <= m ? query( L( x ) , l , m ) : 0 ) + ( m < R ? query( R( x ) , m + 1 , r ) : 0 );
}
ll Q( int l , int r ) {
L = l , R = r;
return query( 1 , 1 , n );
}
 
void build( int x , int l , int r ) {
if( l == r ) {
sum[ x ] = seq[ _id[ l ] ];
} else {
int m = mid( l , r );
build( L( x ) , l , m );
build( R( x ) , m + 1 , r );
maintain( x , l , r );
}
}
 
int X;
 
ll Query() {
ll ans = 0;
while( top[ X ] != 0 ) {
ans += Q( id[ top[ X ] ] , id[ X ] );
X = fa[ top[ X ] ];
}
return ans + Q( id[ 0 ] , id[ X ] );
}
 
void modify() {
if( op == 1 ) {
U( id[ X ] , id[ X ] );
} else {
U( LEFT[ X ] , RIGHT[ X ] );
}
}
 
int main() {
freopen( "test.in" , "r" , stdin );
int m;
cin >> n >> m;
rep( i , n ) scanf( "%d" , seq + i );
edge_init();
rep( i , n - 1 ) {
int u , v;
scanf( "%d%d" , &u , &v );
u-- , v--;
add_edge( u , v );
}
DFS_init();
build( 1 , 1 , n );
while( m-- ) {
scanf( "%d%d" , &op , &X );
X--;
if( op == 3 ) {
printf( "%lld\n" , Query() );
} else {
scanf( "%d" , &v );
modify();
}
}
return 0;
}

-----------------------------------------------------------------------------

4034: [HAOI2015]T2

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 444  Solved: 181
[Submit][Status][Discuss]

Description

有一棵点数为 N 的树,以点 1 为根,且树点有边权。然后有 M 个

操作,分为三种:
操作 1 :把某个节点 x 的点权增加 a 。
操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a 。
操作 3 :询问某个节点 x 到根的路径中所有点的点权和。

Input

第一行包含两个整数 N, M 。表示点数和操作数。

接下来一行 N 个整数,表示树中节点的初始权值。
接下来 N-1 行每行三个正整数 fr, to , 表示该树中存在一条边 (fr, to) 。
再接下来 M 行,每行分别表示一次操作。其中第一个数表示该操
作的种类( 1-3 ) ,之后接这个操作的参数( x 或者 x a ) 。

Output

对于每个询问操作,输出该询问的答案。答案之间用换行隔开。

Sample Input

5 5
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3

Sample Output

6
9
13

HINT

对于 100% 的数据, N,M<=100000 ,且所有输入数据的绝对值都不

会超过 10^6 。

Source

BZOJ 4034: [HAOI2015]T2( 树链剖分 )的更多相关文章

  1. Bzoj 4034: [HAOI2015]T2 树链剖分,子树问题,dfs序

    4034: [HAOI2015]T2 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1841  Solved: 598[Submit][Status] ...

  2. [BZOJ4034] [HAOI2015] T2 (树链剖分)

    Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所 ...

  3. JZYZOJ1539[haoi2015]T2 树链剖分

    http://172.20.6.3/Problem_Show.asp?id=1539 在学校的OJ又写了一次,RE了好多次,原来haoi的时候这道题需要开栈+快读,裸数据结构30分,加上快读50分.o ...

  4. bzoj 4034 [HAOI2015] T2(树链剖分,线段树)

    4034: [HAOI2015]T2 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 1536  Solved: 508[Submit][Status] ...

  5. BZOJ 4034 [HAOI2015]T2(树链剖分)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4034 [题目大意] 有一棵点数为 N 的树,以点 1 为根,且树点有边权. 有 M 个 ...

  6. bzoj 4034: [HAOI2015]T2

    4034: [HAOI2015]T2 Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操 ...

  7. BZOJ 2243: [SDOI2011]染色 [树链剖分]

    2243: [SDOI2011]染色 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 6651  Solved: 2432[Submit][Status ...

  8. [BZOJ - 2819] Nim 【树链剖分 / DFS序】

    题目链接: BZOJ - 2819 题目分析 我们知道,单纯的 Nim 的必胜状态是,各堆石子的数量异或和不为 0 .那么这道题其实就是要求求出树上的两点之间的路径的异或和.要求支持单点修改. 方法一 ...

  9. BZOJ.4515.[SDOI2016]游戏(树链剖分 李超线段树)

    BZOJ 洛谷 每次在路径上加的数是个一次函数,容易看出是树剖+李超线段树维护函数最小值.所以其实依旧是模板题. 横坐标自然是取个确定的距离标准.取每个点到根节点的距离\(dis[i]\)作为\(i\ ...

随机推荐

  1. Web Api帮助页面或用户手册

    我这么玩Web Api(一):帮助页面或用户手册(Microsoft and Swashbuckle Help Page)   前言 你需要为客户编写Api调用手册?你需要测试你的Api接口?你需要和 ...

  2. Spring学习笔记1——IOC: 尽量使用注解以及java代码(转)

    在实战中学习Spring,本系列的最终目的是完成一个实现用户注册登录功能的项目. 预想的基本流程如下: 1.用户网站注册,填写用户名.密码.email.手机号信息,后台存入数据库后返回ok.(学习IO ...

  3. HDU 2136 Largest prime factor

    题目大意:求出比给出数小的互质的质数个数. 题解:直接用筛法求素数,稍微改编一下,将原先的布尔数组变为数组用来记录信息就可以了. 注意点:大的数组定义要放在程序的开头,不要放在main里面,不然会栈溢 ...

  4. HDU 1104 Remainder( BFS(广度优先搜索))

    Remainder Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  5. 3027 - Corporative Network(并差集)

    3027 - Corporative Network A very big corporation is developing its corporative network. In the begi ...

  6. 关于js闭包是否真的会造成内存泄漏(转载)

    闭包是一个非常强大的特性,但人们对其也有诸多无解.一种危言耸听的说法是闭包会造成内存泄露. 局部变量本来应该在函数退出的时候被解除引用,但如果局部变量被封闭在闭包形成的环境中,那么这个局部变量就能一直 ...

  7. CSS3线性渐变linear-gradient

    转自 http://www.w3cplus.com/content/css3-gradient CSS3的线性渐变 一.线性渐变在Mozilla下的应用 -moz-linear-gradient( [ ...

  8. 【转】How to Start Intel Hardware-assisted Virtualization (hypervisor) on Linux to Speed-up Intel Android x86 Emulator

    [转]How to Start Intel Hardware-assisted Virtualization (hypervisor) on Linux to Speed-up Intel Andro ...

  9. 字符串String类

    1. String类是一个密封类.用关键字sealed修饰: 2. 字符串的两个特性:     ·不可变性:string类型变量,一旦声明就表明它是不会被改变的.因此,string中的方法对strin ...

  10. Oracle游标循环更新数据案例

    declare v_XTXMBH number; v_ZJZJZJRQ varchar2(40); cursor c_job is SELECT XT.XTXMBH AS XTXMBH, QJ.ZJZ ...