BZOJ3637 Query on a tree VI(树链剖分+线段树)
考虑对于每一个点维护子树内与其连通的点的信息。为了换色需要,记录每个点黑白两种情况下子树内连通块的大小。
查询时,找到深度最浅的同色祖先即可,这可以比较简单的树剖+线段树乱搞一下(似乎就是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(树链剖分+线段树)的更多相关文章
- 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, ...
- 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 ...
- 【POJ3237】Tree(树链剖分+线段树)
Description You are given a tree with N nodes. The tree’s nodes are numbered 1 through N and its edg ...
- POJ3237 Tree 树链剖分 线段树
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - POJ3237 题意概括 Description 给你由N个结点组成的树.树的节点被编号为1到N,边被编号为1 ...
- 【CF725G】Messages on a Tree 树链剖分+线段树
[CF725G]Messages on a Tree 题意:给你一棵n+1个节点的树,0号节点是树根,在编号为1到n的节点上各有一只跳蚤,0号节点是跳蚤国王.现在一些跳蚤要给跳蚤国王发信息.具体的信息 ...
- Water Tree CodeForces 343D 树链剖分+线段树
Water Tree CodeForces 343D 树链剖分+线段树 题意 给定一棵n个n-1条边的树,起初所有节点权值为0. 然后m个操作, 1 x:把x为根的子树的点的权值修改为1: 2 x:把 ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 )
BZOJ.4034 [HAOI2015]树上操作 ( 点权树链剖分 线段树 ) 题意分析 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 ...
- 2243: [SDOI2011]染色 树链剖分+线段树染色
给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同一段), 如“112221”由3段组 ...
随机推荐
- rman的基于窗口的备份保留策略学习
例如: rman>configure retention policy to recovery window of 7 days; 那么就是说,至少要使得保留下来的备份,可以支持恢复到从当前回溯 ...
- STM32L431仿真卡在HAL_InitTick(TICK_INT_PRIORITY);
1. 使用IAR 8.20版本,STM32L431RBT芯片,JLINK V9仿真器,实际仿真测试的时候卡在如下的函数 /* Use SysTick as time base source and c ...
- dsp6657的helloworld例程测试-第一篇
环境搭建可以参考http://blog.sina.com.cn/s/blog_ed2e19900102xi2j.html 1. 先从mcsdk导入工程,helloworld例程 2. 提示有错误,估计 ...
- Arduino 101/Genuino101使用-第2篇
1. Arduino 101编程只是在ARC的核心上进行,其具体架构为ARCv2EM.. 2. 而Quark核心,从目前可知的信息来看,其应该运行着名为Zephyr的RTOS 3.101并没有EEPR ...
- Angular开发者手册重点翻译之指令(一)
创建自定义的指令 这个文章将解释什么需要在自己的angularjs应用中创建自己的指令,以及如何实现它. 什么是指令 在高的层面上讲,指令是DOM元素中的标记(例如一个属性,一个节点名,注释或者CSS ...
- Android开发笔记——以Volley图片加载、缓存、请求及展示为例理解Volley架构设计
Volley是由Google开源的.用于Android平台上的网络通信库.Volley通过优化Android的网络请求流程,形成了以Request-RequestQueue-Response为主线的网 ...
- NO.05--谈一谈Angular 和 Vue.js 的对比。
几天的vue之后,给需要的盆友们带来一篇对比,也算是我近期之内业余时间的大工程,现在开始: Vue.js 是开源的 JavaScript 框架,能够帮助开发者构建出美观的 Web 界面.当和其它网络工 ...
- Could not resolve placeholder 'jdbc.url' in value "${jdbc.url}"
写完接口之后,发现报了这个错误,查了一下发现,spring不允许使用两个 <context:property-placeholder>
- 搭建Git工作环境
为什么要做版本控制? 在平时的工作中,经常会遇到写文档的事情,而写文档基本都不会一蹴而就,总是会修修改改很多次,而版本控制能够记录每次修改的版本,能够进行回溯.有很多版本控制工具,但是作为一个程序员, ...
- [转]如何设计自适应屏幕大小的网页 Responsive Web Design
随着3G的普及,越来越多的人使用手机上网. 移动设备正超过桌面设备,成为访问互联网的最常见终端.于是,网页设计师不得不面对一个难题:如何才能在不同大小的设备上呈现同样的网页? 手机的屏幕比较小,宽度通 ...