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段组 ...
随机推荐
- ABP中module-zero快速集成微信用户认证
https://personball.com/abp/2019/01/01/introduce-abp-module-zero-external-authenticate
- Qt 利用XML文档,写一个程序集合 三
接上一篇https://www.cnblogs.com/DreamDog/p/9214052.html 滚动区域实现, 滚动区域可以三成分层 第一层,显示内容 中间层,滚动层 第三层,爸爸层 把我们要 ...
- NO--10今天带大家回忆回忆“闭包”吧!
对于‘闭包,我相信很多人都掉进过这个坑里,也相信很多人没能详细的理解这个问题,今天带大家再次走进闭包: 写这篇文章时的心情是十分忐忑的,因为对于我们今天的主角:闭包,很多小伙伴都写过关于它的文章,相信 ...
- Linux建立互信关系(ssh公钥登录)
Linux有多种登录方式,比如telnet.ssh.支持ssh登录方式:口令登录和公钥登录 ssh登录方式:ssh [-l login_name] [-p port] [user@]hostname ...
- 2017年4月8日Office 365 使用CSV文件导入邮件组
国内版 第一步: Import-Module msonline Connect-MsolService 输入用户名密码 第二步: Get-MsolUser" 第三步: Set-Executi ...
- 日本IT行业劳动力缺口达22万 在日中国留学生迎来就业好时机 2017/07/18 11:25:09
作者:倪亚敏 来源:日本新华侨报 发布时间:2017/07/18 11:25:09 据日本政府提供的数据,日本2018年应届毕业生的“求人倍率”已经达到了1.78倍.换言之,就是100名大学生 ...
- Full Binary Tree(二叉树找规律)
Description In computer science, a binary tree is a tree data structure in which each node has at mo ...
- Scrum立会报告+燃尽图(十月二十三日总第十四次)
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2246 项目地址:https://git.coding.net/zhang ...
- 软件工程第九周psp
1.PSP表格 2.进度条 3.饼状图 4.折线图
- 【转】nodeJs学习之项目结构
新建的项目结构应该是这样 bin:项目的启动文件,也可以放其他脚本. node_modules:用来存放项目的依赖库. public:用来存放静态文件(css,js,img). routes:路由控制 ...