题意翻译

你被给定一棵n个点的树,点从1到n编号。每个点可能有两种颜色:黑或白。我们定义dist(a,b)为点a至点b路径上的边个数。

一开始所有的点都是黑色的。

要求作以下操作:

0 i 将点i的颜色反转(黑变白,白变黑)

1 v 询问dist(u,v)的最小值。u点必须为白色(u与v可以相同),显然如果v是白点,查询得到的值一定是0。

特别地,如果作'1'操作时树上没有白点,输出-1。

题解

是QTREE4的弱化版诶……

具体的思路可以看看Qtree4的->这里

注意把求最大改成求最小,还有只需要到点的最短距离,不需要维护子树里的答案了

然后查询的时候本来打算makeroot的……后来发现太麻烦了……直接access+splay,然后查询rmx即可(因为已经在这个splay里深度最大了)

 //minamoto
#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
#define getc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
char buf[<<],*p1=buf,*p2=buf;
inline int read(){
#define num ch-'0'
char ch;bool flag=;int res;
while(!isdigit(ch=getc()))
(ch=='-')&&(flag=true);
for(res=num;isdigit(ch=getc());res=res*+num);
(flag)&&(res=-res);
#undef num
return res;
}
char obuf[<<],*o=obuf;
inline void print(int x){
if(x>) print(x/);
*o++=x%+;
}
const int N=;
int ver[N<<],head[N],Next[N<<];
int rev[N],fa[N],ch[N][],w[N],col[N],lmn[N],rmn[N],len[N],val[N];
multiset<int> s[N];
int n,q,white=,tot;
#define ls ch[x][0]
#define rs ch[x][1]
inline int fir(multiset<int> &s){return s.size()?*s.begin():inf;}
inline int min(int x,int y,int z){return min(x,min(y,z));}
inline bool add(int u,int v){ver[++tot]=v,Next[tot]=head[u],head[u]=tot;}
inline bool isroot(int x){return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;}
inline void init(){for(int i=;i<=n;++i) lmn[i]=rmn[i]=w[i]=inf;}
inline void pushr(int x){
rev[x]^=,swap(ls,rs),swap(lmn[x],rmn[x]);
}
inline void pushup(int x){
if(!x) return;
len[x]=len[ls]+len[rs]+val[x];
lmn[x]=min(lmn[ls],len[ls]+val[x]+min(w[x],fir(s[x]),lmn[rs]));
rmn[x]=min(rmn[rs],len[rs]+min(w[x],fir(s[x]),rmn[ls]+val[x]));
}
inline void pushdown(int x){
if(x&&rev[x]){
pushr(ls),pushr(rs),rev[x]=;
}
}
void rotate(int x){
int y=fa[x],z=fa[y],d=ch[y][]==x;
if(!isroot(y)) ch[z][ch[z][]==y]=x;
fa[x]=z,fa[y]=x,fa[ch[x][d^]]=y,ch[y][d]=ch[x][d^],ch[x][d^]=y,pushup(y);
}
void down(int x){
if(!isroot(x)) down(fa[x]);
pushdown(x);
}
void splay(int x){
down(x);
for(int y=fa[x],z=fa[y];!isroot(x);y=fa[x],z=fa[y]){
if(!isroot(y))
((ch[z][]==y)^(ch[y][]==x))?rotate(x):rotate(y);
rotate(x);
}
pushup(x);
}
void access(int x){
for(int y=;x;x=fa[y=x]){
splay(x);
if(rs) s[x].insert(lmn[rs]);
if(y) s[x].erase(s[x].find(lmn[y]));
rs=y,pushup(x);
}
}
void modify(int x){
access(x),splay(x);
col[x]^=,w[x]=col[x]?:inf;
col[x]?(++white):(--white);
pushup(x);
}
int query(int x){
access(x),splay(x);
return rmn[x];
}
void dfs(int u){
for(int i=head[u];i;i=Next[i]){
int v=ver[i];
if(v==fa[u]) continue;
fa[v]=u,val[v]=,dfs(v);
s[u].insert(lmn[v]);
}
pushup(u);
}
int main(){
//freopen("testdata.in","r",stdin);
n=read();init();
for(int i=;i<n;++i){
int u=read(),v=read();
add(u,v),add(v,u);
}
dfs();q=read();
while(q--){
int op=read(),x=read();
if(op){
if(!white) *o++='-',*o++='';
else if(col[x]) *o++='';
else print(query(x));
*o++='\n';
} else modify(x);
}
fwrite(obuf,o-obuf,,stdout);
return ;
}

QTREE5 - Query on a tree V(LCT)的更多相关文章

  1. SP16580 QTREE7 - Query on a tree VII(LCT)

    题意翻译 一棵树,每个点初始有个点权和颜色(输入会给你) 0 u:询问所有u,v路径上的最大点权,要满足u,v路径上所有点颜色相同 1 u:反转u的颜色 2 u w:把u的点权改成w 题解 Qtree ...

  2. SP16549 QTREE6 - Query on a tree VI(LCT)

    题意翻译 题目描述 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v满足路径u到v上所有节点(包括)都拥 ...

  3. SP2666 QTREE4 - Query on a tree IV(LCT)

    题意翻译 你被给定一棵n个点的带边权的树(边权可以为负),点从1到n编号.每个点可能有两种颜色:黑或白.我们定义dist(a,b)为点a至点b路径上的权值之和. 一开始所有的点都是白色的. 要求作以下 ...

  4. QTREE5 - Query on a tree V——LCT

    QTREE5 - Query on a tree V 动态点分治和动态边分治用Qtree4的做法即可. LCT: 换根后,求子树最浅的白点深度. 但是也可以不换根.类似平常换根的往上g,往下f的拼凑 ...

  5. 洛谷SP16580 QTREE7 - Query on a tree VII(LCT,multiset)

    洛谷题目传送门 思路分析 维护子树最值还是第一次写QwQ 因为子树的最值会变化,所以不能简单地把最值记下来,还要维护一个平衡树,把每个子树的最大值扔进去,来资磁插入.删除和查询最值. 然后我就懒得手写 ...

  6. 洛谷SP16549 QTREE6 - Query on a tree VI(LCT)

    洛谷题目传送门 思路分析 题意就是要维护同色连通块大小.要用LCT维护子树大小就不说了,可以看看蒟蒻的LCT总结. 至于连通块如何维护,首先肯定可以想到一个很naive的做法:直接维护同色连通块,每次 ...

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

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

  8. SPOJ - QTREE5 Query on a tree V 边分治

    题目传送门 题意:给你一棵树, 然后树上的点都有颜色,且原来为黑,现在有2个操作,1 改变某个点的颜色, 2 询问树上的白点到u点的最短距离是多少. 题解: 这里用的还是边分治的方法. 把所有东西都抠 ...

  9. 【洛谷 P1501】 [国家集训队]Tree II(LCT)

    题目链接 Tree Ⅱ\(=\)[模板]LCT+[模板]线段树2.. 分别维护3个标记,乘的时候要把加法标记也乘上. 还有就是模数的平方刚好爆\(int\),所以开昂赛德\(int\)就可以了. 我把 ...

随机推荐

  1. mySQL中插入多条记录

    用一条INSERT向SQL中插入多条记录 2008-12-22 10:07:01|  分类: 记事本_编程技术|举报|字号 订阅     Sql 语法: 插入多行记录 Insert Into Tabl ...

  2. css水平居中,竖直居中技巧(二)

    css水平居中,竖直居中技巧(二)===### 1.效果 ### 2.代码#### 2.1.index.html <!DOCTYPE html> <html lang="z ...

  3. git远程代码库回滚(webstorm下)

    git远程代码库回滚(webstorm下) 1. 场景 添加了一个文件[file-for-test.js]到git的控制下 进行了三次修改,并分别进行了三次commit,最后进行了一次push git ...

  4. 【BZOJ 2120】数颜色【分块/莫队】

    题意 给出n个数字和m个操作.操作有两种.1:查询区间[l,r]内不同种类得数字个数.2: 将下标为p得数字修改为v 分析 如果不是修改操作的话,用莫队贼简单就可以水过,但是因为带了修改就有一些麻烦了 ...

  5. 714. Best Time to Buy and Sell Stock with Transaction Fee有交易费的买卖股票

    [抄题]: Your are given an array of integers prices, for which the i-th element is the price of a given ...

  6. 882. Reachable Nodes In Subdivided Graph

    题目链接 https://leetcode.com/contest/weekly-contest-96/problems/reachable-nodes-in-subdivided-graph/ 解题 ...

  7. 76-Relatives-欧拉函数

    http://poj.org/problem?id=2407 Relatives Time Limit: 1000MS   Memory Limit: 65536K Total Submissions ...

  8. strlen头文件

    #include <string.h> 函数strlen strsep 等等

  9. nhibernate 3.x新特性

    http://www.360doc.com/content/14/0226/17/9316347_355904008.shtml

  10. javascript总结27 :特殊引用类型String/Number/Boolean

    为了方便操作基本数据类型,JavaScript还提供了三个特殊的引用类型:String/Number/Boolean 1  Number 例如: var s1 = "zhangsan&quo ...