LCT...略麻烦...

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

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
  
#define rep( i , n ) for( int i = 0 ; i < n ; ++i )
#define clr( x , c ) memset( x , c , sizeof( x ) )
  
using namespace std;
 
const int maxn = 100000 + 5;
const int maxnode = maxn + 100;
const int MOD = 51061;
const int maxedge = maxn << 1;
 
#define mod( x ) ( ( x ) %= MOD )
 
int n;
 
struct edge {
int to;
edge* next;
};
 
edge* head[ maxn ];
edge EDGE[ maxedge ];
edge* e_pt;
 
void add( int u , int v ) {
e_pt -> to = v;
e_pt -> next = head[ u ];
head[ u ] = e_pt++;
}
 
#define add_edge( u , v ) add( u , v ) , add( v , u )
 
void edge_init() {
e_pt = EDGE;
clr( head , 0 );
}
 
struct Node *pt , *null;
 
struct Node {
Node *ch[ 2 ] , *p , *fa;
int add , mul , sum , v , s;
bool isRoot , rev;
Node() : v( 1 ) , add( 0 ) , mul( 1 ) , sum( 1 ) , s( 1 ) {
ch[ 0 ] = ch[ 1 ] = p = fa = null;
isRoot = true;
rev = false;
}
inline void setc( Node* c , int d ) {
ch[ d ] = c;
c -> p = this;
}
inline bool d() {
return this == p -> ch[ 1 ];
}
inline void relax() {
if( rev ) {
rev = false;
rep( i , 2 ) if( ch[ i ] != null )
   ch[ i ] -> Rev();
}
if( mul != 1 ) {
rep( i , 2 ) if( ch[ i ] != null ) 
   ch[ i ] -> Mul( mul );
mul = 1;
}
if( add ) {
rep( i , 2 ) if( ch[ i ] != null )
   ch[ i ] -> Add( add );
add = 0;
}
}
inline void upd() {
s = ch[ 0 ] -> s + ch[ 1 ] -> s + 1;
mod( sum = ch[ 0 ] -> sum + v + ch[ 1 ] -> sum );
}
inline void Rev() {
rev ^= 1;
swap( ch[ 0 ] , ch[ 1 ] );
}
inline void Add( int ad ) {
mod( add += ad );
mod( sum += 1LL * ad * s % MOD );
mod( v += ad );
}
inline void Mul( int mu ) {
add = 1LL * add * mu % MOD;
mul = 1LL * mul * mu % MOD;
sum = 1LL * sum * mu % MOD;
v = 1LL * v * mu % MOD;
}
inline void setRoot() {
fa = p;
p = null;
isRoot = true;
}
void* operator new( size_t ) {
return pt++;
}
};
 
Node NODE[ maxnode ];
void rot( Node* t ) {
Node* p = t -> p;
p -> relax();
t -> relax();
int d = t -> d();
p -> p -> setc( t , p -> d() );
p -> setc( t -> ch[ d ^ 1 ] , d );
t -> setc( p , d ^ 1 );
p -> upd();
if( p -> isRoot ) {
p -> isRoot = false;
t -> isRoot = true;
t -> fa = p -> fa;
}
}
 
void splay( Node* t , Node* f = null ) {
static Node* S[ maxn ];
int top = 0;
for( Node* o = t ; o != null ; o = o -> p ) S[ ++top ] = o;
while( top ) S[ top-- ] -> relax();
for( Node* p = t -> p ; p != f ; p = t -> p ) {
if( p -> p != f )
   p -> d() != t -> d() ? rot( t ) : rot( p );
rot( t );
}
t -> upd();
}
 
void access( Node* t ) {
for( Node* o = null ; t != null ; o = t , t = t -> fa ) {
splay( t );
t -> ch[ 1 ] -> setRoot();
t -> setc( o , 1 );
}
}
 
void makeRoot( Node* t ) {
access( t );
splay( t );
t -> Rev();
}
 
Node* findRoot( Node* t ) {
access( t );
splay( t );
for( ; t -> ch[ 0 ] != null ; t = t -> ch[ 0 ] )
   t -> relax();
splay( t );
return t;
}
 
void cut( Node* x , Node* y ) {
makeRoot( x );
access( y );
splay( x );
x -> setc( null , 1 );
x -> upd();
y -> p = null;
y -> setRoot();
}
 
void join( Node* x , Node* y ) {
makeRoot( x );
x -> fa = y;
}
 
Node* get( Node* x , Node* y ) {
makeRoot( x );
access( y );
splay( y );
return y;
}
 
void node_init() {
pt = NODE;
null = new( Node );
null -> s = null -> v = null -> sum = 0;
}
 
Node* V[ maxn ];
 
void dfs( int x , int par ) {
for( edge* e = head[ x ] ; e ; e = e -> next ) {
int to = e -> to;
if( to == par ) continue;
dfs( to , x );
V[ to ] -> fa = V[ x ];
}
}
 
void build_tree() {
rep( i , n ) V[ i ] = new( Node );
dfs( 0 , -1 );
}
 
int main() {
freopen( "test.in" , "r" , stdin );
freopen( "test.out" , "w" , stdout );
edge_init();
node_init();
int q , u , v;
cin >> n >> q;
rep( i , n - 1 ) {
scanf( "%d%d" , &u , &v );
u-- , v--;
add_edge( u , v );
}
build_tree();
char op;
while( q-- ) {
scanf( " %c%d%d" , &op , &u , &v );
u-- , v--;
if( op == '-' ) {
cut( V[ u ] , V[ v ] );
scanf( "%d%d" , &u , &v );
u-- , v--;
join( V[ u ] , V[ v ] );
} else if( op == '/' ) {
printf( "%d\n" , get( V[ u ] , V[ v ] ) -> sum );
} else {
int c;
scanf( "%d" , &c );
mod( c );
op != '+' ? get( V[ u ] , V[ v ] ) -> Mul( c ) : get( V[ u ] , V[ v ] ) -> Add( c );
}
}
return 0;
}

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

2631: tree

Time Limit: 30 Sec  Memory Limit: 128 MB
Submit: 2454  Solved: 819
[Submit][Status][Discuss]

Description

 一棵n个点的树,每个点的初始权值为1。对于这棵树有q个操作,每个操作为以下四种操作之一:
+ u v c:将u到v的路径上的点的权值都加上自然数c;
- u1 v1 u2 v2:将树中原有的边(u1,v1)删除,加入一条新边(u2,v2),保证操作完之后仍然是一棵树;
* u v c:将u到v的路径上的点的权值都乘上自然数c;
/ u v:询问u到v的路径上的点的权值和,求出答案对于51061的余数。

Input

  第一行两个整数n,q
接下来n-1行每行两个正整数u,v,描述这棵树
接下来q行,每行描述一个操作

Output

  对于每个/对应的答案输出一行

Sample Input

3 2
1 2
2 3
* 1 3 4
/ 1 1

Sample Output

4

HINT

数据规模和约定

10%的数据保证,1<=n,q<=2000

另外15%的数据保证,1<=n,q<=5*10^4,没有-操作,并且初始树为一条链

另外35%的数据保证,1<=n,q<=5*10^4,没有-操作

100%的数据保证,1<=n,q<=10^5,0<=c<=10^4

Source

BZOJ 2631: tree( LCT )的更多相关文章

  1. BZOJ 2631: tree [LCT splay区间]

    2631: tree Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 3854  Solved: 1292[Submit][Status][Discus ...

  2. [BZOJ - 2631] tree 【LCT】

    题目链接:BZOJ - 2631 题目分析 LCT,像线段树区间乘,区间加那样打标记. 这道题我调了一下午. 提交之后TLE了,我一直以为是写错了导致了死循环. 于是一直在排查错误.直到.. 直到我看 ...

  3. bzoj 2631: tree 动态树+常数优化

    2631: tree Time Limit: 30 Sec  Memory Limit: 128 MBSubmit: 1716  Solved: 576[Submit][Status] Descrip ...

  4. 【BZOJ】2631: tree LCT

    [题意]给定n个点的树,每个点初始权值为1,m次操作:1.x到y的点加值,2.断一条边并连一条边,保证仍是树,3.x到y的点乘值,4.x到y的点权值和取模.n,m<=10^5. [算法]Link ...

  5. BZOJ 2631 tree / Luogu P1501 [国家集训队]Tree II (LCT,多重标记)

    题意 一棵树,有删边加边,有一条链加/乘一个数,有询问一条链的和 分析 LCT,像线段树一样维护两个标记(再加上翻转标记就是三个),维护size,就行了 CODE #include<bits/s ...

  6. BZOJ 2631 tree | Luogu P1501 [国家集训队]Tree II (LCT 多重标记下放)

    链接:https://www.luogu.org/problemnew/show/P1501 题面: 题目描述 一棵n个点的树,每个点的初始权值为1.对于这棵树有q个操作,每个操作为以下四种操作之一: ...

  7. BZOJ 3282: Tree( LCT )

    LCT.. -------------------------------------------------------------------------------- #include<c ...

  8. BZOJ 2631 tree(动态树)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2631 [题目大意] 要求支持链修改,链查询,边断开,连接操作 [题解] 链修改分乘和加 ...

  9. BZOJ 2631 tree 动态树(Link-Cut-Tree)

    题目大意:维护一种树形数据结构.支持下面操作: 1.树上两点之间的点权值+k. 2.删除一条边.添加一条边,保证加边之后还是一棵树. 3.树上两点之间点权值*k. 4.询问树上两点时间点的权值和. 思 ...

随机推荐

  1. Python学习之路——初识Python

    一.第一个程序Hello World: 1.打印输出Hello World: Python2打印方法: >>> print "hello world"hello ...

  2. C-重定向

    说实话,第一次接触重定向这一个概念,感觉是那么的神奇简洁不可思议…………………… freopen() 本来应该是打开的是文件指针,但是分配了指针,使她(亲切)指向了标准输入.输出.错误流. 用 法: ...

  3. win7下Java环境变量配置及说明

    在官网上下载与操作系统对应的JDK(http://www.oracle.com/index.html) 比如我的安装路径是E:\jdk1.7.0_51\JDK 右击计算机---->属性----& ...

  4. delphi 文件夹权限设置(执行一个小脚本的笨办法)

    如题,研究了一天,也没再网上找到比较好的方式,自己做了一个.方法如下: 1.创建一个 cmd 命令文件.2.调用该命令. 代码如下:   S:='echo y|cacls h: /t /c /g ev ...

  5. perl5 第二章 简单变量

    第二章 简单变量  by flamephoenix 一.整型 二.浮点数 三.字符串 基本上,简单变量就是一个数据单元,这个单元可以是数字或字符串.一.整型 1.整型   PERL最常用的简单变量,由 ...

  6. hdoj 1233 还是畅通工程(最小生成树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1233 思路分析:该问题为最小生成树问题,使用kruskal算法或者prim算法即可解决: 代码如下: ...

  7. readv和writev函数

    readv 和 writev 函数用于在一次函数调用中读.写多个非连续缓冲区.有时也将这两个函数称为散布读和聚集写. #include <sys/uio.h> ssize_t readv( ...

  8. 3.5 用NPOI操作EXCEL--巧妙使用Excel Chart

    在NPOI中,本身并不支持Chart等高级对象的创建,但通过l模板的方式可以巧妙地利用Excel强大的透视和图表功能,请看以下例子. 首先建立模板文件,定义两列以及指向此区域的名称“sales”: 创 ...

  9. Jenkins持续集成相关文章整理

    构建iOS持续集成平台(一)——自动化构建和依赖管理 构建iOS持续集成平台(二)——测试框架 构建iOS持续集成平台(三)——CI服务器与自动化部署 使用Jenkins搭建iOS开发的CI服务器 一 ...

  10. 学习:WordXML格式初步分析

    Office2003以上,Word可以以XML文本格式存储,这样就可以使用外部程序创建Word文件,而不需要使用Word的对象.也能够自由的打开分析Word文件,或者发布到自己的Web页面,或者其他更 ...