以1号节点为根,弄出DFS序,我们发现,对于一个询问:(rt,u),以rt为根,u节点的子树中的最小点权,我们可以根据rt,u,1这三个节点在同一条路径上的相对关系来把它转化为以1为根的在DFS序上的区间询问(中间有一种情况要在树上倍增,理解了LCA的话应该很容易写出来)。

收获:

对于只有换根这种改变树的形态的操作,又只询问和子树相关的问题,可以不用动态树。

 /**************************************************************
Problem: 3306
User: idy002
Language: C++
Result: Accepted
Time:2264 ms
Memory:19948 kb
****************************************************************/ #include <cstdio>
#include <iostream>
#define oo 0x3f3f3f3f
#define N 100010
#define P 16
using namespace std; struct Node {
int v;
Node *ls, *rs;
}pool[N*], *tail=pool, *root; int n, m;
int head[N], wght[N], dest[N+N], next[N+N], etot;
int anc[N][P+], dep[N], in[N], out[N], vdf[N], idc; void update( Node *nd ) {
nd->v = min( nd->ls->v, nd->rs->v );
}
Node *build( int lf, int rg ) {
Node *nd = ++tail;
if( lf==rg ) {
nd->v = wght[vdf[lf]];
return nd;
}
int mid=(lf+rg)>>;
nd->ls = build( lf, mid );
nd->rs = build( mid+, rg );
update( nd );
return nd;
}
void modify( Node *nd, int lf, int rg, int pos, int val ) {
if( lf==rg ) {
nd->v = val;
return;
}
int mid=(lf+rg)>>;
if( pos<=mid ) modify( nd->ls, lf, mid, pos, val );
else modify( nd->rs, mid+, rg, pos, val );
update(nd);
}
int query( Node *nd, int lf, int rg, int L, int R ) {
if( L<=lf && rg<=R )
return nd->v;
int mid=(lf+rg)>>;
int rt = oo;
if( L<=mid ) rt = query( nd->ls, lf, mid, L, R );
if( R>mid ) rt = min( rt, query( nd->rs, mid+, rg, L, R ) );
return rt;
}
void adde( int u, int v ) {
etot++;
next[etot] = head[u];
dest[etot] = v;
head[u] = etot;
}
void dfs( int u ) {
++idc;
in[u] = idc;
vdf[idc] = u;
for( int p=; p<=P; p++ )
anc[u][p] = anc[anc[u][p-]][p-];
for( int t=head[u]; t; t=next[t] ) {
int v=dest[t];
anc[v][] = u;
dep[v] = dep[u]+;
dfs(v);
}
out[u] = idc;
}
int climb( int u, int t ) {
for( int p=; t; t>>=,p++ )
if( t& ) u=anc[u][p];
return u;
}
int lca( int u, int v ) {
if( dep[u]<dep[v] ) swap(u,v);
int t=dep[u]-dep[v];
u = climb( u, t );
if( u==v ) return u;
for( int p=P; p>=&&anc[u][]!=anc[v][]; p-- )
if( anc[u][p]!=anc[v][p] ) u=anc[u][p],v=anc[v][p];
return anc[u][];
}
int query( int rt, int u ) {
int ca=lca(rt,u);
if( rt==u ) {
return query( root, , idc, , idc );
} else if( ca==u ) {
int ans1=oo, ans2=oo;
u = climb( rt, dep[rt]-dep[u]- );
if( in[u]>= ) ans1 = query( root, , idc, , in[u]- );
if( out[u]<=n- ) ans2 = query( root, , idc, out[u]+, idc );
return min( ans1, ans2 );
} else {
return query( root, , idc, in[u], out[u] );
}
}
int main() {
scanf( "%d%d", &n, &m );
for( int i=,f,w; i<=n; i++ ) {
scanf( "%d%d", &f, &w );
wght[i] = w;
if( f ) adde(f,i);
}
anc[][] = ;
dep[] = ;
dfs();
root = build( , idc ); int crt=;
for( int t=,x,y; t<=m; t++ ) {
char ch[];
scanf( "%s", ch ); if( ch[]=='V' ) {
scanf( "%d%d", &x, &y );
modify( root, , idc, in[x], y );
} else if( ch[]=='E' ) {
scanf( "%d", &crt );
} else {
scanf( "%d", &x );
printf( "%d\n", query(crt,x) );
}
}
}

bzoj 3306的更多相关文章

  1. BZOJ 3306: 树 LCT + set 维护子树信息

    可以作为 LCT 维护子树信息的模板,写的还是比较优美的. 本地可过,bzoj 时限太紧,一直 TLE #include<bits/stdc++.h> #define setIO(s) f ...

  2. BZOJ 3306 树

    dfs序建线段树+分类讨论+写的有点长. #include<iostream> #include<cstdio> #include<cstring> #includ ...

  3. 【bzoj 3306】树

    Description 给定一棵大小为 n 的有根点权树,支持以下操作:  • 换根  • 修改点权      • 查询子树最小值 Input 第一行两个整数 n, Q ,分别表示树的大小和操作数.  ...

  4. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  5. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  6. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  7. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

  8. centos7 打开mysql 3306端口并 设置外部访问

    mysql安装后默认是localhost访问,如果需要外部访问可以设置一个新的账号把host改为%,意味着所有ip均可以访问 grant all privileges on *.* to 'outUs ...

  9. BZOJ 题目整理

    bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...

随机推荐

  1. 关于app的cpu占用率想到的几个问题

    1.top 命令获取的cpu是手机瞬间的cpu 2.dumpsys获取的是一段时间cpu的平均值?那么这段时间是指哪段,从哪开始到什么时候结束? 3.如果想测试app某操作下的cpu占用情况时候.应该 ...

  2. linux通配符,grep和 egrep区别

    其实主要是正则表达式中的一些特殊语法.在网上找的几篇文章,截取相关部分贴在了下面,方便以后翻阅. 参考:http://hi.baidu.com/sei_zhouyu/item/c18e1a950d2e ...

  3. 关于mysql的wait_timeout参数 设置不生效的问题【转】

    关于wait_timeout 有一次去online set wait_timeout 的时候发现改了不生效,如下: mysql> show variables like 'wait_timeou ...

  4. Django 基于类的视图(CBV)执行流程 CBV 源码分析

    一.CBV(基于类的视图) 视图是可以调用的,它接受请求并返回响应,这不仅仅是一个函数,Django提供了一些可以用作视图的类的例子,这些允许您通过继承或mixin来构建视图并重用代码. 基本示例 D ...

  5. BigDecimal常用方法

    一.介绍 Java中提供了大数字(超过16位有效位)的操作类,即 java.math.BinInteger 类和 java.math.BigDecimal 类,用于高精度计算. 其中 BigInteg ...

  6. mybatis 控制台打印sql脚本

    在mybatis-config.xml文件中加一句 <setting name="logImpl" value="STDOUT_LOGGING" /> ...

  7. 【小程序开发】购物车加减几件demo

    <!-- 主容器 --> <view class="stepper"> <!-- 减号 --> <text class="{{m ...

  8. TF-池化函数 tf.nn.max_pool 的介绍

    转载自此大神 http://blog.csdn.net/mao_xiao_feng/article/details/53453926 max pooling是CNN当中的最大值池化操作,其实用法和卷积 ...

  9. 无需编译app切换线上、测试环境

    在咱们测试过程中,经常需要切换测试环境和线上环境.大致有如下几个方案. 一.服务器地址编译到app中 此种方式需要在代码里保存两套配置,一套指向线上,一套指向测试.通过编译参数分别生成测试包.线上包. ...

  10. C++之可调用对象

    C++中的可调用对象分为以下几种: 函数 函数指针 lambda表达式 bind创建的对象 重载了函数调用运算符(即“()”)的类 函数.函数指针不再介绍.lambda表达式与bind创建的类参考—— ...