传送门

QTREE6QTREE6QTREE6神似,改成了求连通块里的最大值。

于是我们对每条链开一个heapheapheap维护一下即可。

MDMDMD终于1A1A1A链分治了。

代码:

#include<bits/stdc++.h>
#define ri register int
#define fi first
#define se second
using namespace std;
inline int read(){
	int ans=0;
	bool w=1;
	char ch=getchar();
	while(!isdigit(ch)){if(ch=='-')w^=1;ch=getchar();}
	while(isdigit(ch))ans=(((ans<<2)+ans)<<1)+(ch^48),ch=getchar();
	return w?ans:-ans;
}
typedef pair<int,int> pii;
const int N=1e5+5,inf=2e9;
int n,m,tot=0,num[N],pred[N],top[N],bot[N],fa[N],siz[N],hson[N],a[N];
vector<int>e[N];
bool col[N];
struct deletable_heap{
	priority_queue<int>a,b;
	inline void push(const int&x){a.push(x);}
	inline void del(const int&x){b.push(x);}
	inline int top(){while(b.size()&&a.top()==b.top())a.pop(),b.pop();return a.size()?a.top():-inf;}
	inline int size(){return a.size()-b.size();}
}h[N][2];
void dfs1(int p){
	siz[p]=1;
	for(ri i=0,v;i<e[p].size();++i){
		if((v=e[p][i])==fa[p])continue;
		fa[v]=p,dfs1(v),siz[p]+=siz[v];
		if(siz[v]>siz[hson[p]])hson[p]=v;
	}
}
void dfs2(int p,int tp){
	top[p]=tp,bot[tp]=p,pred[num[p]=++tot]=p;
	if(!hson[p])return;
	dfs2(hson[p],tp);
	for(ri i=0,v;i<e[p].size();++i)if((v=e[p][i])!=fa[p]&&v!=hson[p])dfs2(v,v);
}
inline int max(const int&a,const int&b){return a>b?a:b;}
namespace SGT{
	#define lc (p<<1)
	#define rc (p<<1|1)
	#define mid (T[p].l+T[p].r>>1)
	struct Val{
		int ls,rs,f;
		inline void init(const int&x){ls=rs=x,f=x==-inf?0:1;}
	};
	inline Val operator+(const Val&a,const Val&b){
		Val ret;
		ret.f=a.f&b.f;
		ret.ls=a.f?max(a.ls,b.ls):a.ls;
		ret.rs=b.f?max(b.rs,a.rs):b.rs;
		return ret;
	}
	struct Node{int l,r;Val s[2];}T[N<<2];
	inline void Set(int p){
		int k=pred[T[p].l];
		T[p].s[col[k]].init(max(h[k][col[k]].top(),a[k]));
		T[p].s[col[k]^1].init(-inf);
	}
	inline void pushup(int p){
		T[p].s[0]=T[lc].s[0]+T[rc].s[0];
		T[p].s[1]=T[lc].s[1]+T[rc].s[1];
	}
	inline void build(int p,int l,int r){
		T[p].l=l,T[p].r=r;
		if(l==r)return;
		build(lc,l,mid),build(rc,mid+1,r);
	}
	inline void update(int p,int k){
		if(T[p].l==T[p].r)return Set(p);
		update(k<=mid?lc:rc,k),pushup(p);
	}
	inline Val query(int p,int ql,int qr,bool f){
		if(ql<=T[p].l&&T[p].r<=qr)return T[p].s[f];
		if(qr<=mid)return query(lc,ql,qr,f);
		if(ql>mid)return query(rc,ql,qr,f);
		return query(lc,ql,qr,f)+query(rc,ql,qr,f);
	}
	#undef lc
	#undef rc
	#undef mid
}
pii dfs3(int tp){
	for(ri p=tp;p;p=hson[p]){
		for(ri i=0,v;i<e[p].size();++i){
			if((v=e[p][i])==fa[p]||v==hson[p])continue;
			pii tmp=dfs3(v);
			h[p][0].push(tmp.fi),h[p][1].push(tmp.se);
		}
		SGT::update(1,num[p]);
	}
	return pii(SGT::query(1,num[tp],num[bot[tp]],0).ls,SGT::query(1,num[tp],num[bot[tp]],1).ls);
}
inline void update(int p){
	int ft,bt,tp;
	while(p){
		ft=fa[top[p]],tp=top[p],bt=bot[tp];
		if(ft){
			h[ft][0].del(SGT::query(1,num[tp],num[bt],0).ls);
			h[ft][1].del(SGT::query(1,num[tp],num[bt],1).ls);
		}
		SGT::update(1,num[p]);
		if(ft){
			h[ft][0].push(SGT::query(1,num[tp],num[bt],0).ls);
			h[ft][1].push(SGT::query(1,num[tp],num[bt],1).ls);
		}
		p=ft;
	}
}
inline int query(int p){
	int ret,ft,tp,bt,x=p;
	SGT::Val tmp;
	while(p){
		if(col[p]^col[x])return ret;
		ft=fa[top[p]],tp=top[p],bt=bot[tp];
		ret=SGT::query(1,num[p],num[bt],col[p]).ls;
		if(p^tp){
			tmp=SGT::query(1,num[tp],num[p]-1,col[p]);
			ret=max(ret,tmp.rs);
			if(!tmp.f)return ret;
		}
		p=ft;
	}
	return ret;
}
int main(){
	n=read();
	for(ri i=1,u,v;i<n;++i)u=read(),v=read(),e[u].push_back(v),e[v].push_back(u);
	for(ri i=1;i<=n;++i)col[i]=read();
	for(ri i=1;i<=n;++i)a[i]=read();
	dfs1(1),dfs2(1,1),SGT::build(1,1,n),dfs3(1);
	for(ri x,op,tt=read();tt;--tt){
		op=read();
		if(!op)cout<<query(read())<<'\n';
		else if(op==1)col[x=read()]^=1,update(x);
		else x=read(),a[x]=read(),update(x);
	}
	return 0;
}

2019.02.17 spoj Query on a tree VII(链分治)的更多相关文章

  1. 2019.02.17 spoj Query on a tree VI(链分治)

    传送门 题意简述:给你一棵nnn个黑白点的树,支持改一个点的颜色,询问跟某个点颜色相同的连通块大小. 思路: 还是链分治 233 记fi,0/1f_{i,0/1}fi,0/1​表示iii的所有颜色为0 ...

  2. 2019.02.17 spoj Query on a tree V(链分治)

    传送门 题意简述: 给你一棵nnn个黑白点的树,初始全是黑点. 现在支持给一个点换颜色或者求整颗树中离某个点最近的白点跟这个点的距离. 思路: 考虑链分治维护答案,每个链顶用一个堆来维护答案,然后对于 ...

  3. 2019.02.16 spoj Query on a tree IV(链分治)

    传送门 题意简述: 捉迷藏强化版(带有边权,可以为负数) 思路:好吧这次我们不用点分树,我们用听起来更屌的链分治. 直接把树剖成若干条重链,这样保证从任意一个点跳到根节点是不会跳超过logloglog ...

  4. SPOJ Query on a tree 树链剖分 水题

    You are given a tree (an acyclic undirected connected graph) with N nodes, and edges numbered 1, 2, ...

  5. SPOJ QTREE Query on a tree 树链剖分+线段树

    题目链接:http://www.spoj.com/problems/QTREE/en/ QTREE - Query on a tree #tree You are given a tree (an a ...

  6. spoj 375 Query on a tree (树链剖分)

    Query on a tree You are given a tree (an acyclic undirected connected graph) with N nodes, and edges ...

  7. Query on a tree——树链剖分整理

    树链剖分整理 树链剖分就是把树拆成一系列链,然后用数据结构对链进行维护. 通常的剖分方法是轻重链剖分,所谓轻重链就是对于节点u的所有子结点v,size[v]最大的v与u的边是重边,其它边是轻边,其中s ...

  8. spoj QTREE - Query on a tree(树链剖分+线段树单点更新,区间查询)

    传送门:Problem QTREE https://www.cnblogs.com/violet-acmer/p/9711441.html 题解: 树链剖分的模板题,看代码比看文字解析理解来的快~~~ ...

  9. SPOJ 375 Query on a tree 树链剖分模板

    第一次写树剖~ #include<iostream> #include<cstring> #include<cstdio> #define L(u) u<&l ...

随机推荐

  1. XML和实体类之间相互转换(序列化和反序列化)

    我们需要在XML与实体类,DataTable,List之间进行转换,下面是XmlUtil类,该类来自网络并稍加修改. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 ...

  2. Java 身份证号码验证

    身份证号码验证 1.号码的结构 公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成.排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码 2.地址码(前 ...

  3. java数据类型关系及关系

    java中有常见的基本数据类型和引用数据类型,基本数据类型为四类八种如下 整数型(byte,short,int,long) 浮点型(float,double) 字符型(char) 布尔型(boolea ...

  4. spring aop 学习1

    1.配置自动扫描的包 <context:component-scan base-package="com.ddf.spring.aop.impl"/> 2.使用spri ...

  5. Elasticsearch **代码片段

    ```JAVA BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery(); RangeQueryBuilder createTimeQuery ...

  6. ubuntu彻底卸载软件

    找到此软件名称,然后sudo apt-get purge ......(点点为为程序名称),purge参数为彻底删除文件,然后sudo apt-get autoremove,sudo apt-get ...

  7. 干货|技术小白如何在45分钟内发行通证(TOKEN)并上线交易(附流程代码

    https://blog.csdn.net/HiBlock/article/details/80071478

  8. vi 操作

    vi 3种模式:1命令行模式,2插入模式,3末行模式 Vim启动后直接进入的是命令行模式,命令行模式顾名思义就是可以输入各种命令的意思, 1. 命令行下按i键进入“插入模式”,命令行下按:键进入“末行 ...

  9. 二十一、proxyDesign 代理模式

    原理: 时序图: 代码清单: Printable public interface Printable { void setPrinterName(String name); String getPr ...

  10. 小强学渲染之OpenGL的GPU管线

    GPU渲染流水线,是硬件真正体现渲染概念的操作过程,也是最终将图元画到2D屏幕上的阶段.GPU管线涵盖了渲染流程的 几何阶段 和 光栅化阶段,但对开发者而言,只有对顶点和片段着色器有可编程控制权,其他 ...