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

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

#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. poj 3358

    /** 大意: 给定小数(p/q),求其循环节的大小和循环节开始的位置 解法: 若出现循环 ai*2^m= aj%p; 即 2^m %p =1 若2与p 互素,则可由欧拉函数的, 不互素,需将其转化为 ...

  2. IList, ICollection ,IEnumerable AND IEnumerator in C#

    IList, ICollection ,IEnumerable 很显然,这些都是集合接口的定义,先看看定义: // 摘要: // 表示可按照索引单独访问的对象的非泛型集合. [ComVisible(t ...

  3. ThinkPHP 3.1.2 视图-2

    一.模板的使用 (重点) a.规则 模板文件夹下[TPL]/[分组文件夹/][模板主题文件夹/]和模块名同名的文件夹[Index]/和方法名同名的文件[index].html(.tpl) 更换模板文件 ...

  4. MySql学习笔记(转载)

    . 数值类型 -- a. 整型 ----------     类型            字节        范围(有符号位)     tinyint        1字节    - ~        ...

  5. cocos2d-x新手学习之Helloworld(第三篇)[版本号:cocos2d-x-3.1.1]

    上篇中,能够正常执行NDK中的样例.可是由cocos2d-x生成的项目,不能编译成功.上一篇戳这里: http://blog.csdn.net/xjjjjjjjjjjj/article/details ...

  6. 开源html5_kiwijs_helloworld

    本次须要的下载文件已经共享出来 网盘地址 由于我使用的是黑苹果系统, window我就无视了. 开发工具使用 网盘里的 dmg :Sublime Text 打开开发工具后在helloworld中找到 ...

  7. 【iOS知识学习】_UITableView简介

    UITableView在iOS中估计是用的最多的控件了吧,几乎每个app都会用到. 一.它是一个非常重要的类来在table中展示数据. 1.是一个一维的表: 2.是UIScrollView的一个子类: ...

  8. [cocos2d-x]用CCSpriteBatchNode进行文理贴图的优化

    引言: 我们在进行手机游戏开发的过程中,由于手机的内存资源是有限的,那么对纹理贴图的优化是非常有必要的,有可能相同的功能,优化的好与不好对内存资源的消耗是非常明显的,下面我就用一个例子来说明一下. 说 ...

  9. HDU 1711 Number Sequence KMP

    题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=1711 AC代码: #include <iostream> #include <cs ...

  10. 10个JavaScript小技巧

    1.变量转换 看起来很简单,但据我所看到的,使用构造函数,像Array()或者Number()来进行变量转换是常用的做法.始终使用原始数据类型(有时也称为字面量)来转换变量,这种没有任何额外的影响的做 ...