bzoj3637 CodeChef SPOJ - QTREE6 Query on a tree VI 题解
题意:
一棵n个节点的树,节点有黑白两种颜色,初始均为白色。两种操作:1.更改一个节点的颜色;2.询问一个节点所处的颜色相同的联通块的大小。
思路:
1.每个节点记录仅考虑其子树时,假设其为黑色时所处的黑色联通块的大小和假设其为白色时所处的白色联通块的大小(树状数组维护)。
2.查询时找到深度最小的、与该点颜色相同的且两点之间的点颜色均与这两点相同(两点可以重合)(不妨称它为最远祖先)的答案。
3.修改时应该修改该节点的父亲至最远祖先的父亲上的值。
4.用树链剖分和树状数组维护。
5.寻找最远祖先时,跳重链,树状数组维护当前颜色(0为白 1为黑),查询重链上的颜色和,判断是否整段相同。是则继续向上跳,否则二分祖先。
反思:
1.越上面的dfn越小,二分开始打反了(二分看了Po姐的)
2.树链剖分有些生疏,开始时打错死循了。树状数组的应用不熟练。
3.开始时修改时是边找最远祖先边修改的,结果在根周围时出现了问题。
4.根在修改、查询时都特判一下,重链的端点为最远祖先时也特判一下。
代码:
#include<cstdio>
#define M 100005
#define swap(x,y) u=x,x=y,y=u
int n,u,cnt,dfn,p[M],v[M<<],id[M],co[M],sz[M],di[M],dep[M],top[M],hea[M],nex[M<<],ans[M][];
bool col[M]; void ins(int x,int y) { v[++cnt]=y,nex[cnt]=hea[x],hea[x]=cnt; }
void Add(int x,int y) { for (;x<=n;x+=x&-x) co[x]+=y; }
int Ask(int x) { int s=; for (;x;x-=x&-x) s=s+co[x]; return s; }
void add(int x,int y,bool c) { for (;x<=n;x+=x&-x) ans[x][c]+=y; }
int ask(int x,bool c) { int s=; for (;x;x-=x&-x) s=s+ans[x][c]; return s;}
bool pd(int x,int y,bool c)
{ return c && (Ask(y)-Ask(x-))==(y-x+) || (!c) && (Ask(x-)==Ask(y)); }
int read()
{
int x=; char ch=getchar();
for (;ch< || ch>;ch=getchar());
for (;ch> && ch<;ch=getchar()) x=(x<<)+(x<<)+ch-;
return x;
} void dfs(int x)
{
sz[x]=;
for (int i=hea[x],y;i;i=nex[i])
if ((y=v[i])^p[x]) p[y]=x,dep[y]=dep[x]+,dfs(y),sz[x]+=sz[y];
} void dfs(int x,int chain)
{
int i,k=,y;
top[x]=chain,id[x]=++dfn,di[dfn]=x;
for (i=hea[x];i;i=nex[i])
if ((y=v[i])^p[x] && sz[y]>sz[k]) k=y;
if (!k) return; dfs(k,chain);
for (i=hea[x];i;i=nex[i])
if ((y=v[i])^p[x] && y^k) dfs(y,y);
} void change(int x,int y,int v,bool c)
{
for (;top[x]!=top[y];x=p[top[x]])
{
if (dep[top[x]]<dep[top[y]]) swap(x,y);
add(id[top[x]],v,c),add(id[x]+,-v,c);
}
if (dep[x]<dep[y]) swap(x,y);
add(id[y],v,c),add(id[x]+,-v,c);
} int find(int x,bool c)
{
int l,r,t,y,mid;
for (;x^;x=p[y])
{
l=id[y=top[x]],t=r=id[x];
if (!pd(l,r,c))
{
while (l+<r)
if (pd((mid=(l+r)>>),t,c)) r=mid; else l=mid+;
if (pd(l,t,c)) return l; return r;
}
if (col[p[y]]^c) return l;
}
return ;
} int main()
{
n=read(); int i,x,y,m;
for (i=;i<n;++i) x=read(),y=read(),ins(x,y),ins(y,x);
dfs(p[]=),dfs(,),add(,,);
for (i=;i<=n;++i) add(id[i],sz[i],),add(id[i]+,-sz[i],);
for (m=read();m--;)
{
i=read(),x=read();
if (i)
{
i=col[x];if (x-) change(p[x],p[di[find(x,i)]],-ask(id[x],i),i);
if (i) Add(id[x],-); else Add(id[x],); col[x]^=;
i=col[x];if (x-) change(p[x],p[di[find(x,i)]],ask(id[x],i),i);
}
else i=col[x],printf("%d\n",ask(find(x,i),i));
}
return ;
}
bzoj3637 CodeChef SPOJ - QTREE6 Query on a tree VI 题解的更多相关文章
- SPOJ QTREE6 Query on a tree VI 树链剖分
题意: 给出一棵含有\(n(1 \leq n \leq 10^5)\)个节点的树,每个顶点只有两种颜色:黑色和白色. 一开始所有的点都是黑色,下面有两种共\(m(1 \leq n \leq 10^5) ...
- QTREE6 - Query on a tree VI 解题报告
QTREE6 - Query on a tree VI 题目描述 给你一棵\(n\)个点的树,编号\(1\)~\(n\).每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我 ...
- SPOJ 16549 - QTREE6 - Query on a tree VI 「一种维护树上颜色连通块的操作」
题意 有操作 $0$ $u$:询问有多少个节点 $v$ 满足路径 $u$ 到 $v$ 上所有节点(包括)都拥有相同的颜色$1$ $u$:翻转 $u$ 的颜色 题解 直接用一个 $LCT$ 去暴力删边连 ...
- SPOJ QTREE Query on a tree VI
You are given a tree (an acyclic undirected connected graph) with n nodes. The tree nodes are number ...
- SP16549 QTREE6 - Query on a tree VI LCT维护颜色联通块
\(\color{#0066ff}{ 题目描述 }\) 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v ...
- [QTree6]Query on a tree VI
Description: 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v满足路径u到v上所有节点(包括 ...
- 洛谷SP16549 QTREE6 - Query on a tree VI(LCT)
洛谷题目传送门 思路分析 题意就是要维护同色连通块大小.要用LCT维护子树大小就不说了,可以看看蒟蒻的LCT总结. 至于连通块如何维护,首先肯定可以想到一个很naive的做法:直接维护同色连通块,每次 ...
- SP16549 QTREE6 - Query on a tree VI(LCT)
题意翻译 题目描述 给你一棵n个点的树,编号1~n.每个点可以是黑色,可以是白色.初始时所有点都是黑色.下面有两种操作请你操作给我们看: 0 u:询问有多少个节点v满足路径u到v上所有节点(包括)都拥 ...
- 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 ...
随机推荐
- jQuery access()方法
最开始只是想了解attr方法,发现它内部调用了jQuery.access()方法.除了attr,还有prop.text.html.css.data 都是内部调用了jQuery.access()方法,可 ...
- Ionic之存储信息、取出存储信息、注销存储信息
每一个app软件在登录的时候,都会本地存储登录信息,需要用到数据的时候,就直接在本地获取,而不是每一次应用的时候都要请求到服务器来验证登录信息,减少服务器的负担.所以在设计混合HTML5 移动应用程序 ...
- iframe 完全跨域自适应高度
1.跨域访问页面, 需要访问后台的页面,通过后台调转 2.跨域自适应宽高 思路:通过相互嵌套,获取跨域页面的高度,通过src传回到本域,通过parent方法设置主页的iframe的高度 index ...
- 正确使用MySQL JDBC setFetchSize()方法解决JDBC处理大结果
一直很纠结,Oracle的快速返回机制,虽然结果集很多,可是它能很快的显示第一个结果,虽然通过MYSQl的客户端可以做到,但是通过JDBC却不行. 今天用了1个多小时,终于搞定此问题,希望对广大Jav ...
- 诊断Java代码中常见的数据库性能热点问题应该这么做!
“你的Java应用程序的性能是怎样诊断和优化的?不妨看看这两位西医的方子.如果你有更好疗效的药方,也欢迎在评论区告诉我们. 当我在帮助一些开发者或架构师分析及优化Java应用程序的性能时,关键往往不在 ...
- 聊聊JavaScript和Scala的表达式 Expression
我们先看下面这段简单的JavaScript代码. 我在第10行调用了函数f,其中传入的第二个和第三个参数都是一个逗号表达式. 函数f的实现,会检查这两个参数的类型,如果是函数,则执行函数调用,再打印其 ...
- Android(java)学习笔记157:开源框架的文件上传(只能使用Post)
1.文件上传给服务器,服务器端必然要写代码进行支持,如下: 我们新建一个FileUpload.jsp的动态网页,同时我们上传文件只能使用post方式(不可能将上传数据拼凑在url路径下),上传数据Ap ...
- centos7 系统安全加固方案
一.密码长度与有效期 默认配置: [root@i-1y3we23j ~]# cat /etc/login.defs |grep PASS_ |grep -v '#' PASS_MAX_DAYS PAS ...
- uva1352 Colored Cubes LA3401
白书第一章例题8 好麻烦! 正方体每面编号为0-5,那么根据顶点和正面,就能确定形态.一共6*4=24种形态. P[i]表示编号i所在位置.比如P[1]=3,表示第二面转到了第四面. 就可以表示出所有 ...
- docker client和daemom
client 模式 docker命令对应的源文件是docker/docker.go, docker [options] command [arg...] 其中options参数为flag,任何时候执行 ...