传送门

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. python之路——8

    王二学习python的笔记以及记录,如有雷同,那也没事,欢迎交流,wx:wyb199594 学习内容 .1.文件操作 笔记.txt 1.文件路径:D:\python\Day8\笔记.txt 2.编码方 ...

  2. python3:实现字符串的全排列(无重复字符)

    最近在学一些基础的算法,发现我的数学功底太差劲了,特别是大学的这一部分,概率论.线性代数.高数等等,这些大学学的我是忘得一干二净(我当时学的时候也不见得真的懂),导致现在学习算法,非常的吃力.唉!不说 ...

  3. 低级sql语法错误: BadSqlGrammarException

    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760) at org.springf ...

  4. 3. tomcat 内存设置

    -Xms512m -Xmx1024m -XX:PermSize=512M

  5. leetcode55

    bool canJump(vector<int>& nums) { ]; ; i < nums.size() && reach >= i; i++) { ...

  6. Java 就业班 Web框架

  7. IDEA(MAC) 快捷键

    从eclipse到IDEA:从Windows到MAC 有些不习惯,记录一些日常使用的快捷键 1.格式化代码 command+alt+L 2.导包 alt+ enter 3.自动生成该类型的对象 com ...

  8. Object.create() vs new SomeFunction() in javascript

    Object.create builds an object that inherits directly from the one passed as its first argument. Wit ...

  9. JQEUERY案例

    案例效果: 点击显示全部奶粉品牌前: 点击后: 源码: <!DOCTYPE html><html><head> <meta charset="utf ...

  10. list中null或者空的区别

    1.list 空 默认值是空,即没有值 null 理解为没有对list集合分配内存空间,实际上压根就不存在. 也可以这样理解: null  未建立对象 空    建立对象未放入值 例如  我有一个空着 ...