
树链剖分...子树的树链剖分序必定是一段区间 , 先记录一下就好了
---------------------------------------------------------------------------
#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\ ...
随机推荐
- WINDOWS硬件通知应用程序的常方法
摘要:在目前流行的Windows操作系统中,设备驱动程序是操纵硬件的最底层软件接口.为了共享在设备驱动程序设计过程中的经验,给出设备驱动程序通知应用程序的5种方法,详细说明每种方法的原理和实现过程,并 ...
- C# 方法的可选参数、命名参数
原文 http://www.cnblogs.com/lonelyxmas/admin/EditPosts.aspx?opt=1 C#方法的可选参数是.net 4.0最新提出的新的功能,对应简单的重载可 ...
- 基于Visual C++2013拆解世界五百强面试题--题18-程序结果分析2-终结篇
第二部分程序结果分析,分析流程还是写入代码注释中 分析下面程序的输出: #include <stdio.h> int main() { char *a = "hello" ...
- JAVA GUI学习 - 总结
一:项目 二:重要组件补充 三:组件高级操作
- Cocos2d-x C++调用Android弹出提示框
转载请注明地址,谢谢.. Cocos2d-x中提供了一个JniHelper类来让我们对Jni进行操作. (PS:弄了一天想自己写代码操作Jni的,但是总是出错,技术差不得不使用Cocos2d-x现成的 ...
- nvarchar and nchar
Same: 1.store unicode charactor. 2. A charactor is stroed with 2 bytes. Different. 1. nchar 会自动填充数据 ...
- CodeFirst-Section1之小例子
尽可能做到不说一些晦涩难懂的语言,Follow Me...... 环境:Visual Studio 2013+.Net Framework 4.5 1.什么是Code First? 说白了就是先建好C ...
- 新建linux组、用户命令
之前在安装oracle的时候,出现了一个问题:安装Oracle,新建组.用户的时候的一个错误.看这篇博客前,先看这个链接,学习要从解决出现的问题出手. 建立用户组和用户 下面总结一下Linux建立组和 ...
- YII2 Gridview
YII2 Gridview 部分使用规则 1.页面显示的时间戳转换 a. [ 'label'=>'创建日期', 'attribute' => 'created_at', 'filter' ...
- 网站压力测试工具之WebBench
1 Web Bench简介 WebBench是有名的网站压力测试工具,由Lionbridge公司开发,最多可以模拟3万个并发连接去测试网站的负载能力. Webbech能测试处在相同硬件上,不同服务的性 ...