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. C++编程规范之23:头文件应该自给自足

    摘要: 各司其责:应该确保所编写的每个头文件都能够独自进行编译,为此需要包含其内容所依赖的所有头文件. 如果一个文件包含某个头文件时,还要包含另一个头文件才能工作,就会增加交流障碍,给头文件的用户增添 ...

  2. PHP学习笔记7-JSON数据操作

    JSON,全称是JavaScript Object Notation.它是基于JavaScript编程语言ECMA-262 3rd Edition-December 1999标准的一种轻量级的数据交换 ...

  3. fiddler---使用方法1--抓取手机app包

    1.首先fiddler设置

  4. 解决64位系统下IIS 8下Asp+Access网站配置

    一.IIS7的安装 Windows 中IIS8是默认不安装的,所以在安装完windows 8,之后如果需要安装IIS8的话,就要自己动手了. 安装的步骤为:开始>控制面板>程序>打开 ...

  5. java牛人给新人的几点建议

    展望未来,总结过去10年的程序员生涯,给程序员小弟弟小妹妹们的一些总结性忠告 走过的路,回忆起来是那么曲折,把自己的一些心得体会分享给程序员兄弟姐妹们,虽然时代在变化,但是很可能你也会走我已经做过的1 ...

  6. 如何禁止scrollView 的子控件自动滑到 底部或者中间部分

    现象:当一个scrollView 里面包含很多childView,并且整个界面超出屏幕的范围,而且每个childView都获取焦点,scrollView就会自动滑到底部或者中间部分. 可以使用以下几种 ...

  7. 在C#中调用API获取网络信息和流量

    原文 在C#中调用API获取网络信息和流量 最近一项目中要求显示网络流量,而且必须使用C#. 事实上,调用 IpHlpApi.dll 的 GetIfTable API 可以轻易获得网络信息和网络流量. ...

  8. 快速注册Uber司机,兼职月入轻松过万

    Uber是世界领先的即时用车网络平台.当前部分中国城市,Uber司机只需每周完成70单,可获得7000元的激励制度回报司机,月收入近3万元.[加入条件]1. 车辆为本地牌照2. 车龄在5年以内3. 裸 ...

  9. Android学习资料PDF免费大放送,每日更新!有需要的亲看这里

    说明:以前有资料分享的时候,都叫大家留下自己的QQ邮箱,这样被很多的程序猿们认为我是专门来钓你们的QQ邮箱的.为此给大家带来的顾虑,深表抱歉.从现在开始,以后的分享资料我都会放在自己的百度网盘中,提供 ...

  10. golang实现udp接入服务器

    前端通过udp与接入服务器连接,接入服务器与后端tcp服务器维持tcp连接.目录结构及后端tcp服务器代码同上一篇博客. main.go package main import ( "lot ...