以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. 【逆向知识】PE ASLR

    1.知识点 微软从windows vista/windows server 2008(kernel version 6.0)开始采用ASLR技术,主要目的是为了防止缓冲区溢出 ASLR技术会使PE文件 ...

  2. Codeforces Round #504 D. Array Restoration

    Codeforces Round #504 D. Array Restoration 题目描述:有一个长度为\(n\)的序列\(a\),有\(q\)次操作,第\(i\)次选择一个区间,将区间里的数全部 ...

  3. 空洞卷积(dilated Convolution) 与感受野(Receptive Field)

    一.空洞卷积 空洞卷积是是为了解决基于FCN思想的语义分割中,输出图像的size要求和输入图像的size一致而需要upsample,但由于FCN中使用pooling操作来增大感受野同时降低分辨率,导致 ...

  4. java基础65 JavaScript中的Window对象(网页知识)

    1.javaScript组成部分 1.EMCAScript(基本语法)    2.BOM(Browser Object Model):浏览器对象模型            浏览器对象模型中的浏览器的各 ...

  5. 洛谷P1242 新汉诺塔

    传送门啦 首先要将第n个盘子从x到y,那么就要把比n小的盘子全部移到6-x-y,然后将n移到y 仔细想想:6代表的是3根初始柱,3根目标柱. 6-(x+y) 便是我们的中转柱了,因为到这个位置是最优的 ...

  6. SQLSERVER中的系统存储过程的使用的总结

    -----------------------------系统存储过程-------------------------------- --列出SQL Server实例中的数据库sp_database ...

  7. PL/SQL开发中动态SQL的使用方法

    一般的PL/SQL程序设计中,在DML和事务控制的语句中可以直接使用SQL,但是DDL语句及系统控制语句却不能在PL/SQL中直接使用,要想实现在PL/SQL中使用DDL语句及系统控制语句,可以通过使 ...

  8. hdu 5943(素数间隔+二分图匹配)

    Kingdom of Obsession Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Oth ...

  9. Django杂记

    django 中 slice 和 truncatewords 不同用法 django中取一段字符串中的前 N 个字符,可以用 slice和truncatewords ,但是两者是有区别的. djang ...

  10. 宝塔Linux常用命令

    https://www.bt.cn/bbs/thread-1186-1-1.html 2017年3月8日发布全新架构的宝塔Linux 面板3.1Beta版,到现在的5.2.0正式版,历经100多天打磨 ...