这道题是树链剖分的裸题,正在学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. 深入理解Spring系列之八:常用的扩展接口

    转载 https://mp.weixin.qq.com/s/XfhZltSlTall8wKwV_7fKg Spring不仅提供了一个进行快速开发的基础框架,而且还提供了很多可扩展的接口,用于满足一些额 ...

  2. Django 自定义分页类

    分页类代码: class Page(object): ''' 自定义分页类 可以实现Django ORM数据的的分页展示 输出HTML代码: 使用说明: from utils import mypag ...

  3. android的wake_lock介绍

    Wake Lock是一种锁的机制, 只要有人拿着这个锁,系统就无法进入休眠, 可以被用户态程序和内核获得. 这个锁可以是有超时的或者是没有超时的, 超时的锁会在时间过去以后自动解锁. 如果没有锁了或者 ...

  4. elk系列7之通过grok分析apache日志【转】

    preface 说道分析日志,我们知道的采集方式有2种: 通过grok在logstash的filter里面过滤匹配. logstash --> redis --> python(py脚本过 ...

  5. 多个id或class属性相同的元素绑定事件

    <td class="tools"><a href="javascript:void(0);" status="0" na ...

  6. C基础 time.h 简单思路扩展

    前言 - time 简单需求 时间业务相关代码. 基本属于框架的最底层. 涉及的变动都很小. 以前参与游戏研发时候, 这方面需求不少, 各种被策划花式吊打. 转行开发互联网服务之后很少遇到这方面需求. ...

  7. Django项目上传到AWS服务器上

    EC2是亚马逊(Amazon.com)提供的弹性云计算服务:Apache是一个跨平台的Web服务器端软件,可以使Python.PHP.Perl等语言编写的程序运行在服务器上:Django是一个Web程 ...

  8. AWS 使用总结

    A.升配置的流程: 1.新开一台配置较高的机器; 2.将新机器和老机器的磁盘都取消关联,注意需要记录下老机器的磁盘分区设备名,如:/dev/sda1: 3.将老机器的磁盘挂载到新机器上,磁盘分区设备名 ...

  9. 更换git用户名或密码

    Windows10下更换Git用户名或密码:https://jingyan.baidu.com/article/642c9d3435a6e9644a46f732.html git清除用户名密码 git ...

  10. CentOS 7.1使用yum安装MySql5.6.24

    http://www.cnblogs.com/yuanfeiblog/p/5276492.html