
树链剖分...子树的树链剖分序必定是一段区间 , 先记录一下就好了
---------------------------------------------------------------------------
#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 树链剖分,子树问题,dfs序
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1841 Solved: 598[Submit][Status] ...
- [BZOJ4034] [HAOI2015] T2 (树链剖分)
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所 ...
- JZYZOJ1539[haoi2015]T2 树链剖分
http://172.20.6.3/Problem_Show.asp?id=1539 在学校的OJ又写了一次,RE了好多次,原来haoi的时候这道题需要开栈+快读,裸数据结构30分,加上快读50分.o ...
- bzoj 4034 [HAOI2015] T2(树链剖分,线段树)
4034: [HAOI2015]T2 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1536 Solved: 508[Submit][Status] ...
- BZOJ 4034 [HAOI2015]T2(树链剖分)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=4034 [题目大意] 有一棵点数为 N 的树,以点 1 为根,且树点有边权. 有 M 个 ...
- bzoj 4034: [HAOI2015]T2
4034: [HAOI2015]T2 Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操 ...
- BZOJ 2243: [SDOI2011]染色 [树链剖分]
2243: [SDOI2011]染色 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 6651 Solved: 2432[Submit][Status ...
- [BZOJ - 2819] Nim 【树链剖分 / DFS序】
题目链接: BZOJ - 2819 题目分析 我们知道,单纯的 Nim 的必胜状态是,各堆石子的数量异或和不为 0 .那么这道题其实就是要求求出树上的两点之间的路径的异或和.要求支持单点修改. 方法一 ...
- BZOJ.4515.[SDOI2016]游戏(树链剖分 李超线段树)
BZOJ 洛谷 每次在路径上加的数是个一次函数,容易看出是树剖+李超线段树维护函数最小值.所以其实依旧是模板题. 横坐标自然是取个确定的距离标准.取每个点到根节点的距离\(dis[i]\)作为\(i\ ...
随机推荐
- C# DES加解密
加密 public static string Encrypt(string sourceString, string key, string iv) { try { byte[] btKey = E ...
- 【LeetCode题意分析&解答】33. Search in Rotated Sorted Array
Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...
- iOS 表视图(UITableVIew)的使用方法(1)表视图的示例
表视图继承自UIScrollView,所以有着大多UIScrollView的操作特性,诸如手指控制内容的滚动,内容视图到顶端或者低端时的自动反弹等.配合UINavigationController的导 ...
- synchronized和vilatile
第一个程序 public class Test06 implements Runnable{ public int a = 0; public static void main(String[] ar ...
- (iOS)viewController背景透明化
#ifdef __IPHONE_8_0 ) { [UIApplication sharedApplication].keyWindow.rootViewController.providesPrese ...
- php定界符 <<< 的作用及使用注意事项
按照原样输出,包括换行符.特殊字符等 任何特殊字符都不需要转义,比如双引号.单引号,它会按照原样输出 像在双引号字符串中一样使用php的变量输出 定界符<<<,当需要输出大段文本时, ...
- 【浏览器那些基础】Android平台有那些CPU类型
在编译Android应用的时候,需要配置支持的CPU类型,而目前Android支持的CPU类型包含了ARM和X86,所以在编译前需要指定CPU类型(不同的cpu的特性不一样): X86系列的 expo ...
- c++的正整数高精度加减乘除
数值计算之高精度加减乘除 一. 高精度正整数的高精度计算 1.加法 2.减法 减法和加法的最大区别在于:减法是从高位开始相减,而加法是从低位开始相加 3.乘法:用高精度加法实现 l 乘法的主 ...
- [置顶] P2P网贷对推动社会发展的影响
P2P网贷对推动社会发展的影响 1 真正的支持了实体经济,一般借款人就在几万或者50万以下 2 关照小微经济,新型行业.一般小微经济的创新更高,对社会的发展最大化. 3盘活存量 放到银行.保险.国债一 ...
- Eclipse快捷键 今天又学会了几个不常用的 收藏了
1.Ctrl+e 打开所有已经打开的文件列表,当你使用Eclipse打开了N多文件的时候,需要找到一个你之前打开过 的文件,是不是就很费 ...