这道题是树链剖分的裸题,正在学LCT,用LCT写了,发现LCT代码比树链剖分还短点(但我的LCT跑极限数据用的时间大概是kuangbin大神的树链剖分的1.6倍,所以在spoj上是850ms卡过的)。

收获:

  1、边转换成点(即若存在边(u,v),则新加一个点z代表边,将z连接u和v,z的点权就是(u,v)的边权,非边点的权设为-oo),然后对边权的统计就变成了对点权的统计(这是LCT中处理边信息的通法之一)。

  2、若要连接两个点u,v,先让它们分别称为根,然后将其中一个的path-parent设为另一个。

  3、若要查找(u,v)的边点,运用“夹逼法”,先让两个点在一条重链上(即同一棵splay树),再splay(u,0)和splay(v,u),这样v的一个子树就是边点(具体来说,可以先让u成为根,再access(v),splay(u,0),splay(v,u),此时v的左儿子必定是边点)

 #include <cstdio>
#include <iostream>
#define maxn 20010
#define oo 0x3f3f3f3f
#define max(a,b) ((a)>(b)?(a):(b))
using namespace std; struct LCT {
int pnt[maxn], pre[maxn], son[maxn][], val[maxn], mxv[maxn], ntot;
bool tag[maxn]; inline void update( int nd ) {
mxv[nd] = max( val[nd], max( mxv[son[nd][]], mxv[son[nd][]] ) );
}
void rotate( int nd, int d ) {
int p = pre[nd];
int s = son[nd][!d];
int ss = son[s][d]; son[nd][!d] = ss;
son[s][d] = nd;
if( p ) son[p][ nd==son[p][] ] = s;
else pnt[s] = pnt[nd]; pre[nd] = s;
pre[s] = p;
if( ss ) pre[ss] = nd; update( nd );
update( s );
}
inline void pushdown( int nd ) {
if( tag[nd] ) {
int &ls = son[nd][], &rs = son[nd][];
swap( ls, rs );
tag[ls] ^= ;
tag[rs] ^= ;
tag[nd] = ;
}
}
void splay( int nd, int top= ) {
static int stk[maxn], spt;
int u = nd;
for( spt=; u; u=pre[u] )
stk[spt++] = u;
while( spt-- )
pushdown( stk[spt] );
while( pre[nd]!=top ) {
int p = pre[nd];
int nl = nd==son[p][];
if( pre[p]==top ) {
rotate( p, nl );
} else {
int pp = pre[p];
int pl = p==son[pp][];
if( nl==pl ) {
rotate( pp, pl );
rotate( p, nl );
} else {
rotate( p, nl );
rotate( pp, pl );
}
}
}
}
void init( int n ) {
for( int i=; i<=n; i++ ) {
pre[i] = pnt[i] = son[i][] = son[i][] = tag[i] = ;
mxv[i] = val[i] = -oo;
}
}
void access( int nd ) {
int u = nd;
int v = ;
while( u ) {
splay( u );
int s = son[u][];
pre[s] = ;
pnt[s] = u;
pre[v] = u;
son[u][] = v;
v = u;
u = pnt[u];
}
splay( nd );
}
void makeroot( int nd ) {
access( nd );
tag[nd] ^= ;
}
void link( int u, int v ) {
makeroot(u);
makeroot(v);
pnt[u] = v;
}
void modify( int e, int w ) {
splay(e);
val[e] = w;
update( e );
}
int query( int u, int v ) {
makeroot(u);
access(v);
return max(val[v],mxv[son[v][]]);
}
}; int n;
LCT LT; int main() {
int T;
scanf( "%d", &T );
while( T-- ) {
scanf( "%d", &n );
LT.init(n+n-);
for( int i=,u,v,w; i<n; i++ ) {
scanf( "%d%d%d", &u, &v, &w );
LT.modify( n+i, w );
LT.link( u, n+i );
LT.link( v, n+i );
}
while() {
char ch[];
scanf( "%s", ch );
if( ch[]=='Q' ) {
int u, v;
scanf( "%d%d", &u, &v );
printf( "%d\n", LT.query(u,v) );
} else if( ch[]=='C' ) {
int e, w;
scanf( "%d%d", &e, &w );
LT.modify( n+e, w );
} else break;
}
}
}

spoj 375 query on a tree LCT的更多相关文章

  1. SPOJ 375. Query on a tree (动态树)

    375. Query on a tree Problem code: QTREE You are given a tree (an acyclic undirected connected graph ...

  2. SPOJ 375. Query on a tree (树链剖分)

    Query on a tree Time Limit: 5000ms Memory Limit: 262144KB   This problem will be judged on SPOJ. Ori ...

  3. 动态树(Link Cut Tree) :SPOJ 375 Query on a tree

    QTREE - Query on a tree #number-theory You are given a tree (an acyclic undirected connected graph) ...

  4. spoj 375 Query on a tree(树链剖分,线段树)

      Query on a tree Time Limit: 851MS   Memory Limit: 1572864KB   64bit IO Format: %lld & %llu Sub ...

  5. spoj 375 Query on a tree (树链剖分)

    Query on a tree You are given a tree (an acyclic undirected connected graph) with N nodes, and edges ...

  6. SPOJ 375 Query on a tree 树链剖分模板

    第一次写树剖~ #include<iostream> #include<cstring> #include<cstdio> #define L(u) u<&l ...

  7. SPOJ 375 Query on a tree(树链剖分)(QTREE)

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...

  8. SPOJ 375 Query on a tree【树链剖分】

    题目大意:给你一棵树,有两个操作1.修改一条边的值,2.询问从x到y路径上边的最大值 思路:如果树退化成一条链的话线段树就很明显了,然后这题就是套了个树连剖分,调了很久终于调出来第一个模板了 #inc ...

  9. SPOJ 375 Query on a tree(树链剖分)

    https://vjudge.net/problem/SPOJ-QTREE 题意: 给出一棵树,树上的每一条边都有权值,现在有查询和更改操作,如果是查询,则要输出u和v之间的最大权值. 思路: 树链剖 ...

随机推荐

  1. JSTL标签库笔记

    1. 概述 JSTL(Jsp Standard Tag Library)即JSP标准标签库,只能运行在支持JSP1.2↑和Servlet2.3↑规范的容器上. 通常情况下我们在编写JSP页面的时候,在 ...

  2. css_input[checked]复选框去掉默认样式并添加新样式

    效果对比: “\2713”实体符号√ :如有兴趣查看详细实体符号请点这里 代码实现: <!DOCTYPE html> <html> <head> <meta ...

  3. perl6 struct2-045 EXP

    测试站点: http://www.yutian.com.cn/index.action http://www.hjxzyzz.com:8088/pfw/login.action 代码如下: use v ...

  4. Mac Sublime Vim模式 方向键无法长按

    终端输入 sublime2: defaults write com.sublimetext.2 ApplePressAndHoldEnabled -bool false sublime3: defau ...

  5. Mac OS X 编译android内核 error: elf.h: No such file or directory 的解决方法

    1. 从网上下个elf.h放到scripts/mod/文件夹(http://www.rockbox.org/tracker/9006?getfile=16683) 2. 修改两个文件mk_elfcon ...

  6. python中的pydoc

    在终端上输入pydoc会显示以下信息 pydoc - the Python documentation tool pydoc <name> ... Show text documentat ...

  7. C++——stoi函数

    版权声明:本文系原创,转载请声明出处. 1. 函数原型 , ); , ); 2. 参数说明 str String object with the representation of an integr ...

  8. Transport failed: java.io.EOFException

    ActiveMQ服务端有时会报Transport failed: java.io.EOFException这样的错误,这是由客户端丢失连接并反复尝试连接导致的,不是什么大问题,有时网络波动就会产生这种 ...

  9. ActiveMQ-如何使用JMS API?

    JMS编程模型 JMS定义了Java中访问消息中间件的一组接口,主要包括ConnectionFactory.Connection.Session.Destination.MessageProducer ...

  10. PDO和mysqli对比

    PHP中,如何选择PDO和mysqli呢?本文做个简单的比较 1)总的比较   PDO MYSQLI 数据库支持 12种不同的数据库支持 支持MYSQL API OOP OOP和过程 命名参数 支持 ...