Description

一棵树,支持三种操作,修改点权,修改颜色,问所有与他路径上颜色相同的点的最大权,包含这两个点.

Sol

LCT.

用LCT来维护重边,对于每个节点在建一个set用来维护轻边,这样Link和Cut是时候就非常好操作了,直接Access一下,Splay一下,直接删掉就可以了.

因为set是不统计重边的,然后对于每个节点的信息由他的父亲来保存,因为一个节点可能有很多儿子但一定只有一个父亲.

还有一个问题就是每个点的权值不能建全局的,因为维护的两颗LCT不能够同时删除,所以每个LCT都要有个点权的数组.

Code

/**************************************************************
Problem: 3639
User: BeiYu
Language: C++
Result: Accepted
Time:4060 ms
Memory:16276 kb
****************************************************************/ #include <bits/stdc++.h>
using namespace std; #define debug(a) cout<<#a<<"="<<a<<" "
typedef long long LL;
const int N = 1e5+50; inline int in(int x=0,char ch=getchar(),int v=1) {
while(ch>'9' || ch<'0') v=ch=='-'?-1:v,ch=getchar();
while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();return x*v; } int n,q;
vector < int > g[N];
int col[N],F[N]; struct LinkCutTree {
int f[N],ch[N][2];
int mx[N],w[N];
multiset< int,greater< int > > s[N]; #define lc(o) ch[o][0]
#define rc(o) ch[o][1] int isrt(int o) { return f[o]==0 || (lc(f[o])!=o && rc(f[o])!=o); }
void Update(int o) {
mx[o]=w[o];
if(!s[o].empty()) mx[o]=max(mx[o],*s[o].begin());
if(lc(o)) mx[o]=max(mx[o],mx[lc(o)]);
if(rc(o)) mx[o]=max(mx[o],mx[rc(o)]);
}
void Rot(int o) {
int p=f[o],k=f[p],r=rc(p)==o;
if(!isrt(p)) ch[k][rc(k)==p]=o;
f[ch[o][r^1]]=p,f[p]=o,f[o]=k;
ch[p][r]=ch[o][r^1],ch[o][r^1]=p;
Update(p),Update(o);
}
void Splay(int o) {
// cout<<"S"<<endl;
for(;!isrt(o);) {
int p=f[o],k=f[p];
if(isrt(p)) Rot(o);
else if((rc(p)==o)==(rc(k)==p)) Rot(p),Rot(o);
else Rot(o),Rot(o);
}Update(o);
}
void Access(int o) {
// cout<<"A"<<endl;
for(int p=0;o;p=o,o=f[o]) {
Splay(o);
if(rc(o)) s[o].insert(mx[rc(o)]);
if(rc(o)=p,p) s[o].erase(s[o].find(mx[p]));
}
}
void Link(int o) {
// cout<<"L"<<endl;
Access(F[o]),Splay(F[o]),Splay(o);
f[o]=F[o],rc(f[o])=o;
}
void Cut(int o) {
// cout<<"C"<<endl;
Access(o),Splay(o),f[lc(o)]=0,lc(o)=0;
}
void Change(int o,int v) {
// cout<<"M"<<endl;
Access(o),Splay(o),w[o]=v,Update(o);
}
int Query(int o) {
// cout<<"Q"<<endl;
Access(o),Splay(o);
int x=o;
for(;lc(x);x=lc(x));Splay(x);
if(col[x]!=col[o]) return mx[rc(x)];
else return mx[x];
}
}py[2]; void AddEdge(int u,int v) { g[u].push_back(v); }
void DFS(int u,int fa) {
for(int i=0,v;i<(int)g[u].size();i++) if((v=g[u][i])!=fa) {
F[v]=u,py[col[v]].f[v]=u;
DFS(v,u);
// debug(py[col[v]].mx[v])<<endl;
py[col[v]].s[u].insert(py[col[v]].mx[v]);
}py[0].Update(u),py[1].Update(u);
}
void init() {
n=in();
for(int i=1,u,v;i<n;i++) {
u=in(),v=in(),AddEdge(u,v),AddEdge(v,u);
}
for(int i=1;i<=n;i++) col[i]=in();
for(int i=1;i<=n;i++) py[0].mx[i]=py[0].w[i]=py[1].mx[i]=py[1].w[i]=in();
DFS(1,1);
// debug(py[1].mx[1])<<endl;
} int main() {
// freopen("in.in","r",stdin);
init();
for(int q=in();q--;) {
int opt=in(),u=in(),v;
if(opt==0) printf("%d\n",py[col[u]].Query(u));
else if(opt==1) {
if(F[u]) py[col[u]].Cut(u);
col[u]^=1;
if(F[u]) py[col[u]].Link(u);
} else {
v=in();
py[0].Change(u,v);
py[1].Change(u,v);
}
}
return 0;
}

  

BZOJ 3639: Query on a tree VII的更多相关文章

  1. BZOJ 3639: Query on a tree VII LCT_set维护子树信息

    用 set 维护子树信息,细节较多. Code: #include <cstring> #include <cstdio> #include <algorithm> ...

  2. bzoj 3637: Query on a tree VI 树链剖分 && AC600

    3637: Query on a tree VI Time Limit: 8 Sec  Memory Limit: 1024 MBSubmit: 206  Solved: 38[Submit][Sta ...

  3. bzoj3639: Query on a tree VII

    Description You are given a tree (an acyclic undirected connected graph) with n nodes. The tree node ...

  4. [BZOJ 3637]Query on a tree VI

    偶然看见了这题,觉得自己 QTREE.COT 什么的都没有刷过的真是弱爆了…… 一道思路很巧妙的题,终于是在约大爷的耐心教导下会了,真是太感谢约大爷了. 这题显然是树链剖分,但是链上维护的东西很恶心. ...

  5. 2019.02.17 spoj Query on a tree VII(链分治)

    传送门 跟QTREE6QTREE6QTREE6神似,改成了求连通块里的最大值. 于是我们对每条链开一个heapheapheap维护一下即可. MDMDMD终于1A1A1A链分治了. 代码: #incl ...

  6. SP16580 QTREE7 - Query on a tree VII

    Description 一棵树,每个点初始有个点权和颜色(0/1) 0 u :询问所有u,v 路径上的最大点权,要满足u,v 路径上所有点的颜色都相同 1 u :反转u 的颜色 2 u w :把u 的 ...

  7. BZOJ 3637: Query on a tree VI LCT_维护子树信息_点权转边权_好题

    非常喜欢这道题. 点权转边权,这样每次在切断一个点的所有儿子的时候只断掉一条边即可. Code: #include <cstring> #include <cstdio> #i ...

  8. [spojQTREE7]Query on a tree VII

    即QTREE5和QTREE6组合,即将原本维护子树范围内点数改为维护子树范围内最小值即可,由于最小值没有可减性,因此需要使用set (虽然形式上与QTREE5类似,但QTREE5维护的信息更巧妙一些, ...

  9. BZOJ 1803 Query on a tree III

    树上主席树. 我靠这是第k小吧..... #include<iostream> #include<cstdio> #include<cstring> #includ ...

随机推荐

  1. [LeetCode] First Unique Character in a String 字符串第一个不同字符

    Given a string, find the first non-repeating character in it and return it's index. If it doesn't ex ...

  2. [LeetCode] 3Sum Smaller 三数之和较小值

    Given an array of n integers nums and a target, find the number of index triplets i, j, k with 0 < ...

  3. .NET WebAPI 实现图片上传(包括附带参数上传图片)

    博主的项目,客户端是APP,考虑到以后也可能会应用到微信端.网站等,图片上传方法就需要兼容多端,并且以目前的设计,不允许非登录用户上传图片,就得在上传时解决附带参数上传图片的问题. 先来看看后台方法( ...

  4. Ajax入门(二)

    接收服务器返回的消息 1,定义触发Ajax的js效果 2,创建Ajax方法 如果返回的数据是XML,则需使用aj.responseXML 3,接收服务器返回的消息,并显示在网页上 错误案例:直接接收服 ...

  5. 打包SpringBoot工程并部署

    使用工具:Eclipse Linux下JDK版本:jdk-7u79-linux-x64.tar.gz 一.打包成jar并部署 步骤如下: 首先上pom.xml: <project xmlns=& ...

  6. Android 提醒公共方法 Notification

    SimpAndroidFarme是近期脑子突然发热想做的android快速开发的框架,目标是模块化 常用的控件,方便新手学习和使用.也欢迎老鸟来一起充实项目:项目地址 今天的目标是做一个公共的提醒方法 ...

  7. background-size

    语法: background-size:length|percentage|cover|contain length:设置背景图像的宽度和高度, 第一个值为宽度,第二个值为高度. 如果只设置一个值,则 ...

  8. Android基础测试题(二)

    今天给大家带来的是Android基础测试题(二) 题目要求: 定义一个5位长度的整型数组并初始化,然后构建方法根据用户传入的数字判断是否存在数组中,如果存在,返回所在位置,如果不存在,返回-1 首先第 ...

  9. SQL语句

    数据查询:SELECT 以下所有的查询都基于以下的表格: 学生表:STUDENT(SNO,Sname,ssex,sage,sdept); 课程表:course(cno,cnama,cpno,ccred ...

  10. PL/SQL循环

    1.if循环做判断 SET SERVEROUTPUT ON accept num prompt 'qinshuu'; DECLARE pnum NUMBER :=& num ; BEGIN T ...