题解 \(by\;zj\varphi\)

首先考虑,如果将一个点修改成了黑点,那么它能够造成多少贡献。

它先会对自己的子树中的答案造成 \(w_x\) 的贡献。

考虑祖先时,它会对不包括自己的子树造成 \(w_fa\) 的贡献。

那么思路很显然,直接暴力向上更新,若更新到一个祖先,它已经被更新过了,那么更新完它之后直接退出就行,因为再向上,一定已经被更新过了。

实现的过程用在 \(\rm dfs\) 序上建线段树即可。

这样,每个点最多被更新一次,在询问时,最多重复更新一个点,所以总复杂度为 \(\mathcal O\rm((n+m)logn)\)

Code
#include<bits/stdc++.h>
#define ri register signed
#define p(i) ++i
namespace IO{
char buf[1<<21],*p1=buf,*p2=buf;
#define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?(-1):*p1++
struct nanfeng_stream{
template<typename T>inline nanfeng_stream &operator>>(T &x) {
ri f=1;x=0;register char ch=getchar();
while(!isdigit(ch)) {if (ch=='-') x=-1;ch=getchar();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return x=f?x:-x,*this;
}
}cin;
}
using IO::cin;
namespace nanfeng{
#define FI FILE *IN
#define FO FILE *OUT
template<typename T>inline T cmax(T x,T y) {return x>y?x:y;}
template<typename T>inline T cmin(T x,T y) {return x>y?y:x;}
static const int N=1e5+7;
int first[N],w[N],ld[N],rd[N],B[N],fa[N],t=1,n,m,tot,ol,nm;
char s[N];
struct edge{int v,nxt;}e[N<<1];
inline void add(int u,int v) {
e[t].v=v,e[t].nxt=first[u],first[u]=t++;
e[t].v=u,e[t].nxt=first[v],first[v]=t++;
}
void dfs(int x,int f) {
ld[x]=p(tot);
for (ri i(first[x]),v;i;i=e[i].nxt) {
if ((v=e[i].v)==f) continue;
fa[v]=x;
dfs(v,x);
}
rd[x]=tot;
}
struct Seg{
#define ls(x) (x<<1)
#define rs(x) (x<<1|1)
#define up(x) T[x].mx=cmax(T[ls(x)].mx,T[rs(x)].mx)
struct segmenttree{int mx,lz;}T[N<<2];
inline void down(int x) {
if (!T[x].lz) return;
T[ls(x)].mx=cmax(T[ls(x)].mx,T[x].lz);
T[rs(x)].mx=cmax(T[rs(x)].mx,T[x].lz);
T[ls(x)].lz=cmax(T[ls(x)].lz,T[x].lz);
T[rs(x)].lz=cmax(T[rs(x)].lz,T[x].lz);
T[x].lz=0;
}
int query(int x,int p,int l,int r) {
if (l==r) return T[x].mx;
int mid(l+r>>1);
down(x);
if (p<=mid) return query(ls(x),p,l,mid);
else return query(rs(x),p,mid+1,r);
}
void update(int x,int k,int l,int r,int lt,int rt) {
if (l<=lt&&rt<=r) {
T[x].mx=cmax(T[x].mx,k);
return (void)(T[x].lz=cmax(T[x].lz,k));
}
int mid(lt+rt>>1);
down(x);
if (l<=mid) update(ls(x),k,l,r,lt,mid);
if (r>mid) update(rs(x),k,l,r,mid+1,rt);
up(x);
}
}T;
inline void update(int x) {
ri nw=x,ns=x;
T.update(1,w[x],ld[nw],rd[nw],1,n);
B[nw]=1;
nw=fa[nw];
while(nw) {
for (ri i(first[nw]),v;i;i=e[i].nxt) {
if ((v=e[i].v)==ns||v==fa[nw]) continue;
T.update(1,w[nw],ld[v],rd[v],1,n);
}
if (B[nw]) return;
T.update(1,w[nw],ld[nw],ld[nw],1,n);
B[nw]=1;
ns=fa[ns],nw=fa[nw];
}
}
inline int main() {
//FI=freopen("nanfeng.in","r",stdin);
//FO=freopen("nanfeng.out","w",stdout);
cin >> n >> m;
for (ri i(1);i<=n;p(i)) cin >> w[i];
for (ri i(1),u,v;i<n;p(i)) cin >> u >> v,add(u,v);
dfs(1,0);
for (ri i(1),v;i<=m;p(i)) {
scanf("%s",s+1);
cin >> v;
if (s[1]=='Q') {
if (!nm) puts("-1");
else printf("%d\n",T.query(1,ld[v],1,n));
} else p(nm),update(v);
}
return 0;
}
}
int main() {return nanfeng::main();}

NOIP 模拟 $29\; \rm 最近公共祖先$的更多相关文章

  1. NOIP 模拟 $29\; \rm 完全背包问题$

    题解 \(by\;zj\varphi\) 一道 \(\rm dp\) 题. 现将所有种类从小到大排序,然后判断,若最小的已经大于了 \(\rm l\),那么直接就是一个裸的完全背包,因为选的总数量有限 ...

  2. NOIP 模拟 $29\; \rm 最长不下降子序列$

    题解 \(by\;zj\varphi\) 观察这个序列,发现模数很小,所以它的循环节很小. 那么可以直接在循环节上做最长上升子序列,但是循环节中的逆序对会对拼接后的答案造成影响. 没有必要找逆序对个数 ...

  3. noip模拟29[简单的板子题](虽然我不会)

    \(noip模拟29\;solutions\) 这次考试给我最大的伤害,让我意识到了差距 这场考试可以说是非常的简单,就是简单到,看两眼,打个表就有结果了 但是呢?我考得非常的完蛋,只有30pts 据 ...

  4. NOIp 图论算法专题总结 (1):最短路、最小生成树、最近公共祖先

    系列索引: NOIp 图论算法专题总结 (1) NOIp 图论算法专题总结 (2) NOIp 图论算法专题总结 (3) 最短路 Floyd 基本思路:枚举所有点与点的中点,如果从中点走最短,更新两点间 ...

  5. 8.3考试总结(NOIP模拟19)[最长不下降子序列·完全背包问题·最近公共祖先]

    一定要保护自己的梦想,即使牺牲一切. 前言 把人给考没了... 看出来 T1 是一个周期性的东西了,先是打了一个暴力,想着打完 T2 T3 暴力就回来打.. 然后,就看着 T2 上头了,后来发现是看错 ...

  6. hiho_1069_最近公共祖先3

    题目 给出一棵家族树,树上的节点可以由名字唯一标识.给出若干个查询,查询的内容为两个名字,结果为两个名字的最近公共祖先. 题目链接: 最近公共祖先 分析 在线的RMQ + LCA 算法,先用dfs将树 ...

  7. D5 LCA 最近公共祖先

    第一题: POJ 1330 Nearest Common Ancestors POJ 1330 这个题可不是以1为根节点,不看题就会一直wa呀: 加一个找根节点的措施: #include<alg ...

  8. 【IT笔试面试题整理】寻找二叉树两节点的最近的公共祖先

    [试题描述] 求二叉树中任意两个节点的最近公共祖先也称为LCA问题(Lowest Common Ancestor). 二叉查找树 如果该二叉树是二叉查找树,那么求解LCA十分简单. 基本思想为:从树根 ...

  9. NOIP模拟 1

    NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. #   用  户  名   ...

随机推荐

  1. Ionic命令笔记

    Ionic命令:ionic serve 开启服务调试ionic cordova prepare android 生成android原生项目 ionic cordova run browser 打包成混 ...

  2. Lua控制语句

    目录 1. 控制结构 if-else 单个 if 分支 型 两个分支: if-else 型 多个分支: if-elseif-else型 2. while 型控制结构 3. repeat控制结构 4. ...

  3. Codeforces Round #139 (Div. 2) 题解

    vp上古场次ing CF225A Dice Tower 1.题目简述: 有 \(n\) 个骰子被叠在了一起.对于每个骰子上的一个数,与它对面的数的和始终为 \(7\) . 你是小明,你只能从正面看这个 ...

  4. C语言:体现\r的结果

    #include <stdio.h> #include <windows.h> //体现\r的结果 //转义字符\r,回车,将光标移动到当前行最开始 main() { char ...

  5. 『与善仁』Appium基础 — 4、常用ADB命令(一)

    目录 1.启动和关闭ADB服务 2.查看ADB版本 3.指定adb server的网络端口 4.查询已连接设备/模拟器 5.获取安卓系统版本 6.为命令指定目标设备 7.发送文件到手机 8.从手机拉取 ...

  6. JAVA程序系统测试感受

    JAVA课程才刚刚开始,就仿佛经历了一场劫难,让我们叫苦连天,苦不堪言.暑假学的一些皮毛java知识,到了真正需要写一个相对完整的软件系统,就如同废材一样,实在是用不上来.我看着小民哥布置的考试内容, ...

  7. 12. Mysql基础入门

    课程大纲 • 数据库概述 • MySQL基本操作 • MySQL索引基础 • MySQL高级特性

  8. R绘图(7): 把散点图的点换成扇形

    前几天分析了一批单细胞TCR的数据,需要画这样一个图: 行是不同的样本,列是不同的T细胞类型,每一个位置点的大小表示T细胞的数目多少,并且还需要根据T细胞所属的克隆型类型涂色.这个图用来描述TCR是我 ...

  9. 基于JSP的学生考勤管理系统(MySQL版)

    介绍:基于JSP的学生考勤管理系统(MySQL版)1.包含源程序,数据库脚本.代码和数据库脚本都有详细注释.2.课题设计仅供参考学习使用,可以在此基础上进行扩展完善.开发环境:Eclipse ,MyS ...

  10. CentOS更换网易yum源

    最新内容和地址参见http://mirrors.163.com/.help/centos.html 1 首先备份/etc/yum.repos.d/CentOS-Base.repo mv /etc/yu ...