考虑对于每一个点维护子树内与其连通的点的信息。为了换色需要,记录每个点黑白两种情况下子树内连通块的大小。

  查询时,找到深度最浅的同色祖先即可,这可以比较简单的树剖+线段树乱搞一下(似乎就是qtree3),具体的,可以维护一下区间是否全黑/白,线段树上二分。换色会造成一个连通块分裂并产生新连通块,这只会影响到祖先节点的信息。同样树剖+线段树暴力改上去即可。

  因为写的实在太丑没有一个oj能过,darkbzoj上42个点跑到第38个T掉了。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=;char c=getchar();
while (c<''||c>'') {if (c=='-') f=-;c=getchar();}
while (c>=''&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return x*f;
}
#define N 100010
int n,m,p[N],color[N],t=;
int dfn[N],id[N],top[N],fa[N],son[N],size[N],cnt=;
int L[N<<],R[N<<],tree[][N<<],lazy[][N<<],same[][N<<];
struct data{int to,nxt;
}edge[N<<];
void addedge(int x,int y){t++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
void dfs1(int k)
{
size[k]=;color[k]=;
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=fa[k])
{
fa[edge[i].to]=k;
dfs1(edge[i].to);
size[k]+=size[edge[i].to];
if (size[edge[i].to]>size[son[k]]) son[k]=edge[i].to;
}
}
void dfs2(int k,int from)
{
id[k]=++cnt;dfn[cnt]=k;
top[k]=from;
if (son[k]) dfs2(son[k],from);
for (int i=p[k];i;i=edge[i].nxt)
if (edge[i].to!=fa[k]&&edge[i].to!=son[k]) dfs2(edge[i].to,edge[i].to);
}
void build(int k,int l,int r)
{
L[k]=l,R[k]=r;same[][k]=;
if (l==r){tree[][k]=size[dfn[l]];tree[][k]=;return;}
int mid=l+r>>;
build(k<<,l,mid);
build(k<<|,mid+,r);
}
void down(int k)
{
tree[][k<<]+=lazy[][k],tree[][k<<|]+=lazy[][k];
tree[][k<<]+=lazy[][k],tree[][k<<|]+=lazy[][k];
lazy[][k<<]+=lazy[][k],lazy[][k<<|]+=lazy[][k];
lazy[][k<<]+=lazy[][k],lazy[][k<<|]+=lazy[][k];
lazy[][k]=lazy[][k]=;
}
int getsame(int k,int l,int r,int p)
{
if (L[k]==l&&R[k]==r) return same[p][k];
if (lazy[p][k]) down(k);
int mid=L[k]+R[k]>>;
if (r<=mid) return getsame(k<<,l,r,p);
else if (l>mid) return getsame(k<<|,l,r,p);
else return getsame(k<<,l,mid,p)&getsame(k<<|,mid+,r,p);
}
int query1(int k,int l,int r,int p)
{
if (L[k]==R[k]) return same[p][k]?l:;
if (lazy[p][k]) down(k);
int mid=L[k]+R[k]>>;
if (r<=mid) return query1(k<<,l,r,p);
else if (l>mid) return query1(k<<|,l,r,p);
else return getsame(k,mid,r,p)?query1(k<<,l,mid,p):query1(k<<|,mid+,r,p);
}
int queryance(int x,int p)
{
int ans=id[x];
while ()
{
int y=query1(,id[top[x]],id[x],p);
if (!y) break;
if (y>id[top[x]]) return y;
ans=id[top[x]];
if (x==) break;
x=fa[top[x]];
}
return ans;
}
int query(int k,int x,int p)
{
if (L[k]==R[k]) return tree[p][k];
if (lazy[p][k]) down(k);
int mid=L[k]+R[k]>>;
if (x<=mid) return query(k<<,x,p);
else return query(k<<|,x,p);
}
void modify(int k,int l,int r,int x,int p)
{
if (L[k]==l&&R[k]==r) {tree[p][k]+=x,lazy[p][k]+=x;return;}
if (lazy[p][k]) down(k);
int mid=L[k]+R[k]>>;
if (r<=mid) modify(k<<,l,r,x,p);
else if (l>mid) modify(k<<|,l,r,x,p);
else modify(k<<,l,mid,x,p),modify(k<<|,mid+,r,x,p);
}
void modifycolor(int k,int x,int p,int op)
{
if (L[k]==R[k]) {same[p][k]=op;return;}
int mid=L[k]+R[k]>>;
if (x<=mid) modifycolor(k<<,x,p,op);
else modifycolor(k<<|,x,p,op);
same[p][k]=same[p][k<<]&&same[p][k<<|];
}
void modifyance(int x,int p,int s,int y)
{
while (top[x]!=top[y])
{
modify(,id[top[x]],id[x],s,p);
x=fa[top[x]];
}
modify(,id[y],id[x],s,p);
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj3637.in","r",stdin);
freopen("bzoj3637.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read();
for (int i=;i<n;i++)
{
int x=read(),y=read();
addedge(x,y),addedge(y,x);
}
fa[]=;dfs1();
dfs2(,);
build(,,n);
m=read();
while (m--)
{
int op=read(),x=read(),y=queryance(x,color[x]);
if (op)
{
if (id[x]==y)
{
modifycolor(,id[x],color[x],);
color[x]^=;
modifycolor(,id[x],color[x],);
y=queryance(x,color[x]);
if (x>)
modifyance(fa[x],color[x],query(,id[x],color[x]),fa[dfn[y]]),
modify(,id[fa[x]],id[fa[x]],-query(,id[x],color[x]^),color[x]^);
}
else
{
if (x>)
modifyance(fa[x],color[x],-query(,id[x],color[x]),fa[dfn[y]]),
modify(,id[fa[x]],id[fa[x]],query(,id[x],color[x]^),color[x]^);
modifycolor(,id[x],color[x],);
color[x]^=;
modifycolor(,id[x],color[x],);
}
}
else printf("%d\n",query(,y,color[x]));
}
return ;
}

BZOJ3637 Query on a tree VI(树链剖分+线段树)的更多相关文章

  1. Spoj Query on a tree SPOJ - QTREE(树链剖分+线段树)

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

  2. Aizu 2450 Do use segment tree 树链剖分+线段树

    Do use segment tree Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.bnuoj.com/v3/problem_show ...

  3. 【POJ3237】Tree(树链剖分+线段树)

    Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...

  4. POJ3237 Tree 树链剖分 线段树

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ3237 题意概括 Description 给你由N个结点组成的树.树的节点被编号为1到N,边被编号为1 ...

  5. 【CF725G】Messages on a Tree 树链剖分+线段树

    [CF725G]Messages on a Tree 题意:给你一棵n+1个节点的树,0号节点是树根,在编号为1到n的节点上各有一只跳蚤,0号节点是跳蚤国王.现在一些跳蚤要给跳蚤国王发信息.具体的信息 ...

  6. Water Tree CodeForces 343D 树链剖分+线段树

    Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...

  7. 【BZOJ-2325】道馆之战 树链剖分 + 线段树

    2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec  Memory Limit: 256 MBSubmit: 1153  Solved: 421[Submit][Statu ...

  8. POJ3237 (树链剖分+线段树)

    Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...

  9. BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )

    BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...

  10. 2243: [SDOI2011]染色 树链剖分+线段树染色

    给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221”由3段组 ...

随机推荐

  1. 微服务(SOP)日志管理

    问题: 大型企业应用规模大,调试 / 解决问题由于在生产环境中不会有开发环境的调试工具,如果需要模拟还原当时的环境, 目前的解决办法是进行日志记录 日志记录的常用方式: 使用SpringAop进行切入 ...

  2. pgpool-II的master-slave模式的分析

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL集群方案相关索引页     回到顶级页面:PostgreSQL索引页 现象描述: 客户来邮件,问:为何Pgpool-II ...

  3. 使用WinIO库实现保护模式下的IO和内存读写

    问题已解决: 原因是函数的调用方式与WinIO中不一致,使用的时候漏掉了__stdcall. 函数原定义为: 在实际的GPIO读写中遇到以下问题: SetPortVal可正常写入,但是GetPortV ...

  4. day2 Opencv + image

    [参考网站]http://backyardlife.duapp.com/duan/ 1.目标: 读入一幅图像,怎样显示一幅图像,以及如何保存一幅图像 cv2.imread(),cv2.imshow() ...

  5. dsp6657的helloworld例程测试-第二篇-CFG文件

    1. 上一篇疑问,int StackTest()这个函数是怎么运行的,后来在.cfg文件找到了答案,.cfg包含丰富的信息,对于用惯C语言的,确实不太习惯 var Memory = xdc.useMo ...

  6. python实现socket通信

    python实现socket很简单,保证你的环境有响应的python环境就可以,我使用的是socket,demo代码如下: server端程序: # coding:utf-8 import socke ...

  7. Python中的矩阵操作

    Numpy 通过观察Python的自有数据类型,我们可以发现Python原生并不提供多维数组的操作,那么为了处理矩阵,就需要使用第三方提供的相关的包. NumPy 是一个非常优秀的提供矩阵操作的包.N ...

  8. Unity中StopCoroutine不起作用怎么办

    1,只有StartCoroutine使用一个字符串方法名时才能用StopCoroutine(string CoroutineName)停用. 2, public Coroutine coroutine ...

  9. mac安装pkg 一直“正在验证” 卡着

    今天换了新mac, 但是之前wireshark(抓包工具) 不能用了 ,要安装Xquartz. 下载之后一直卡着, 网上找了半天没有解决方法. 最后我重启一下就好了... 重启一下. 2. 15款ma ...

  10. ubuntu10.10安装使用vnc

    原文发表于:2010-12-15转载至cu于:2012-07-21 搭安全试验的环境,在vmware上安装了ubuntu10.10(大学的时候用过,最早用的好像是6系列吧).安装好后想用远程桌面控制, ...