bzoj 3306
以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的更多相关文章
- BZOJ 3306: 树 LCT + set 维护子树信息
可以作为 LCT 维护子树信息的模板,写的还是比较优美的. 本地可过,bzoj 时限太紧,一直 TLE #include<bits/stdc++.h> #define setIO(s) f ...
- BZOJ 3306 树
dfs序建线段树+分类讨论+写的有点长. #include<iostream> #include<cstdio> #include<cstring> #includ ...
- 【bzoj 3306】树
Description 给定一棵大小为 n 的有根点权树,支持以下操作: • 换根 • 修改点权 • 查询子树最小值 Input 第一行两个整数 n, Q ,分别表示树的大小和操作数. ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- bzoj 4610 Ceiling Functi
bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...
- centos7 打开mysql 3306端口并 设置外部访问
mysql安装后默认是localhost访问,如果需要外部访问可以设置一个新的账号把host改为%,意味着所有ip均可以访问 grant all privileges on *.* to 'outUs ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
随机推荐
- 再战CS231-快速排序
1.用python实现快速排序 print quicksort([3,6,8,10,1,2,1]) # Prints "[1, 1, 2, 3, 6, 8, 10]" ''' @a ...
- 【NOIP题解】NOIP2017 TG D2T3 列队
列队,NOIP2017 TG D2T3. 树状数组经典题. 题目链接:洛谷. 题意: Sylvia 是一个热爱学习的女孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. ...
- innobackupex 相关语法讲解【转】
innobackupex 相关语法讲解 连接服务器 The database user used to connect to the server and its password are speci ...
- MySQL异步复制、半同步复制详解
MySQL数据复制的原理图大致如下: 从上图我们可以看出MySQL数据库的复制需要启动三个线程来实现: 其中1个在主服务器上,另两个在从服务器上.当发出START SLAVE时,从服务器创建一个I/O ...
- vs2010,vs2012注释快捷键
注释:VS2010是(Ctrl+E,C),VS2012是(Ctrl+K, Ctrl+C) 反注释:VS2010是(Ctrl+E,U),VS2012是(Ctrl+K, Ctrl+U)
- Flask:使用Eclipse+PyDev插件编辑基于package的项目
Windows 10家庭中文版,Python 3.6.4,Flask 1.0.2,Eclipse Oxygen.1a Release (4.7.1a),PyDev 6.3.2 本文记录了 使用Ecli ...
- java基础54 网络通讯的三要素及网络/网页编程的概述
1.概述 网络编程注意解决的是计算机(手机.平板.....)之间的数据传输问题. 网络编程:不需要基于html基础上,就可以进行数据间的传输.比如:FeiQ.QQ.微信..... ...
- Oracle 中count(1) 、count(*) 和count(列名) 函数的区别
1)count(1)与count(*)比较: 1.如果你的数据表没有主键,那么count(1)比count(*)快2.如果有主键的话,那主键(联合主键)作为count的条件也比count(*)要快3. ...
- linux nat网络配置
1. 2 . 3. BOOTPROTO = static ONBOOT=yes #开启自动启用网络连接 IPADDR0=192.168.21.128 #设置IP地址 PREFIXO0=24 #设 ...
- 数据库中INFORMATION_SCHEMA的说明及使用
第一个查询看看库里有多少个表,表名等select * from INFORMATION_SCHEMA.TABLES information_schema这张数据表保存了MySQL服务器所有数据库的信息 ...