以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. 79.ZYNQ内部私有定时器中断

    上篇文章实现了了PS接受来自PL的中断,本片文章将在ZYNQ的纯PS里实现私有定时器中断.每个一秒中断一次,在中断函数里计数加1,通过串口打印输出. *本文所使用的开发板是Miz702(兼容zedbo ...

  2. Tslib步骤以及出现问题的解决方案【转】

    转自:http://forum.eepw.com.cn/thread/267828/1 嵌入式设备中触摸屏使用非常广泛,但触摸屏的坐标和屏的坐标是不对称的,需要校准.校准广泛使用的是开源的tslib. ...

  3. REX系统2

    REX(Real Time Executive)是一个面向嵌入式应用的,简单高效的,抢先式,多任务实时操作系统,支持基于优先级的任务调度算法(支持优先级反转).它提供了任务控制,任务同步,互斥,定时器 ...

  4. java基础47 装饰着模式设计

    1.装饰者模式 增强一个类的功能,而且还可以让这些装饰类相互装饰 2.装饰者设计模式的步骤 1.在装饰类的内部维护一个被装饰类的引用    2.让装饰者有一个共同的父类或者父接口 3.实例 packa ...

  5. C实现线程池

    简介:这里使用linux下的互斥锁和条件变量实现了一个线程池.代码由一个未知作者完成,第二任作者补充优化. 本人仅仅是做了一些注释工作. 代码如下: /*! .h */ #include <st ...

  6. Ad Hoc Distributed Queries的启用与关闭

    启用Ad Hoc Distributed Queries: exec sp_configure 'show advanced options',1 reconfigure exec sp_config ...

  7. SonarQube代码质量管理工具的安装(Linux)

    一.安装配置sonar 1.Sonar介绍 Sonar是一个用于代码质量管理的开源平台,用于管理Java源代码的质量.通过插件机制,Sonar 可以集成不同的测试工具,代码分析工具,以及持续集成工具, ...

  8. Azkaban(一)Azkaban的基础介绍

    一.为什么需要工作流调度器 1.一个完整的数据分析系统通常都是由大量任务单元组成: shell 脚本程序,java 程序,mapreduce 程序.hive 脚本等 2.各任务单元之间存在时间先后及前 ...

  9. 备份恢复-----system表空间损坏

    无法进行关库,报错如下 SQL> shutdown immediate ORA-01122: database file 1 failed verification checkORA-01110 ...

  10. 黑马程序员_java基础笔记(09)...HTML基本知识、CSS、JavaScript、DOM

    —————————— ASP.Net+Android+IOS开发..Net培训.期待与您交流! —————————— 基本标签(a.p.img.li.table.div.span).表单标签.ifra ...