Gym - 102040F Path Intersection (树链剖分+线段树)
题意:给出棵树上的k条路径,求这些路径的公共点数量。
将每条路径上的点都打上标记,被标记过k次的点就是公共点了。由于公共点形成的区间是连续的,因此直接在线段树上暴搜即可在$O(logn)$求出一条链上公共点的数量。
怎样找被标记过k次的点呢?可以维护一个区间最大值mx和一个区间最小值mi,如果mx=mi=k说明这一段区间上的点全都为公共点。
清除标记加个线段树区间赋值即可(也可以把标记过的路径一条一条去掉)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e4+,mod=1e9+;
int hd[N],n,ne,Q,m,fa[N],son[N],siz[N],dep[N],top[N],dfn[N],rnk[N],tot,ka;
int mx[N<<],mi[N<<],lza[N<<],lzs[N<<];
struct E {int v,nxt;} e[N<<];
void addedge(int u,int v) {e[ne]= {v,hd[u]},hd[u]=ne++;}
void dfs1(int u,int f,int d) {
fa[u]=f,son[u]=,siz[u]=,dep[u]=d;
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(v==fa[u])continue;
dfs1(v,u,d+),siz[u]+=siz[v];
if(siz[v]>siz[son[u]])son[u]=v;
}
}
void dfs2(int u,int tp) {
top[u]=tp,dfn[u]=++tot,rnk[dfn[u]]=u;
if(son[u])dfs2(son[u],top[u]);
for(int i=hd[u]; ~i; i=e[i].nxt) {
int v=e[i].v;
if(v==fa[u]||v==son[u])continue;
dfs2(v,v);
}
}
#define ls (u<<1)
#define rs (u<<1|1)
#define mid ((l+r)>>1)
void pu(int u) {mx[u]=max(mx[ls],mx[rs]),mi[u]=min(mi[ls],mi[rs]);}
void change(int u,int x,int f) {
if(f==)lza[u]=,lzs[u]=mx[u]=mi[u]=x;
else lza[u]+=x,mx[u]+=x,mi[u]+=x;
}
void pd(int u) {
if(~lzs[u])change(ls,lzs[u],),change(rs,lzs[u],),lzs[u]=-;
if(lza[u])change(ls,lza[u],),change(rs,lza[u],),lza[u]=;
}
void upd(int L,int R,int x,int f,int u=,int l=,int r=tot) {
if(l>=L&&r<=R) {change(u,x,f); return;}
if(l>R||r<L)return;
pd(u),upd(L,R,x,f,ls,l,mid),upd(L,R,x,f,rs,mid+,r),pu(u);
}
int qry(int L,int R,int u=,int l=,int r=tot) {
if(l>=L&&r<=R&&mx[u]==m&&mi[u]==m)return r-l+;
if(l>R||r<L||mx[u]!=m)return ;
pd(u);
return qry(L,R,ls,l,mid)+qry(L,R,rs,mid+,r);
}
void upd2(int u,int v) {
for(; top[u]!=top[v]; u=fa[top[u]]) {
if(dep[top[u]]<dep[top[v]])swap(u,v);
upd(dfn[top[u]],dfn[u],,);
}
if(dep[u]<dep[v])swap(u,v);
upd(dfn[v],dfn[u],,);
}
int qry2(int u,int v) {
int ret=;
for(; top[u]!=top[v]; u=fa[top[u]]) {
if(dep[top[u]]<dep[top[v]])swap(u,v);
ret+=qry(dfn[top[u]],dfn[u]);
}
if(dep[u]<dep[v])swap(u,v);
ret+=qry(dfn[v],dfn[u]);
return ret;
}
int main() {
int T;
for(scanf("%d",&T); T--;) {
printf("Case %d:\n",++ka);
memset(hd,-,sizeof hd),ne=tot=;
scanf("%d",&n);
for(int i=; i<n; ++i) {
int u,v;
scanf("%d%d",&u,&v);
addedge(u,v);
addedge(v,u);
}
dfs1(,,),dfs2(,);
scanf("%d",&Q);
while(Q--) {
upd(,tot,,);
scanf("%d",&m);
for(int i=; i<m; ++i) {
int u,v;
scanf("%d%d",&u,&v);
upd2(u,v);
if(i==m-)printf("%d\n",qry2(u,v));
}
}
}
}
Gym - 102040F Path Intersection (树链剖分+线段树)的更多相关文章
- 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 ...
- 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, ...
- 【BZOJ-2325】道馆之战 树链剖分 + 线段树
2325: [ZJOI2011]道馆之战 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1153 Solved: 421[Submit][Statu ...
- 【BZOJ2243】[SDOI2011]染色 树链剖分+线段树
[BZOJ2243][SDOI2011]染色 Description 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的 ...
- BZOJ2243 (树链剖分+线段树)
Problem 染色(BZOJ2243) 题目大意 给定一颗树,每个节点上有一种颜色. 要求支持两种操作: 操作1:将a->b上所有点染成一种颜色. 操作2:询问a->b上的颜色段数量. ...
- POJ3237 (树链剖分+线段树)
Problem Tree (POJ3237) 题目大意 给定一颗树,有边权. 要求支持三种操作: 操作一:更改某条边的权值. 操作二:将某条路径上的边权取反. 操作三:询问某条路径上的最大权值. 解题 ...
- bzoj4034 (树链剖分+线段树)
Problem T2 (bzoj4034 HAOI2015) 题目大意 给定一颗树,1为根节点,要求支持三种操作. 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子 ...
- HDU4897 (树链剖分+线段树)
Problem Little Devil I (HDU4897) 题目大意 给定一棵树,每条边的颜色为黑或白,起始时均为白. 支持3种操作: 操作1:将a->b的路径中的所有边的颜色翻转. 操作 ...
- HDU 2460 Network(双连通+树链剖分+线段树)
HDU 2460 Network 题目链接 题意:给定一个无向图,问每次增加一条边,问个图中还剩多少桥 思路:先双连通缩点,然后形成一棵树,每次增加一条边,相当于询问这两点路径上有多少条边,这个用树链 ...
随机推荐
- 05-前端之jQuery
一. jQuery是什么? <1> jQuery由美国人John Resig创建,至今已吸引了来自世界各地的众多 javascript高手加入其team. <2> jQuery ...
- 语音识别LD3320
一.概述 1.芯片介绍 LD3320 是一颗基于非特定人语音识(SI-ASR:Speaker-Independent Automatic Speech Recognition)技术的语音识/声控芯片 ...
- JAVA实验三及总结
JAVA第五周作业 Java实验报告三 第一题 1.已知字符串:"this is a test of java".按要求执行以下操作:(要求源代码.结果截图.) (1).统计该字符 ...
- ASP.NET Core WebApi使用Swagger生成API说明文档【特性版】
⒈新建ASP.NET Core WebAPi项目 ⒉添加 NuGet 包 Install-Package Swashbuckle.AspNetCore ⒊Startup中配置 using System ...
- Luogu P1600[NOIP2016]day1 T2天天爱跑步
号称是noip2016最恶心的题 基本上用了一天来搞明白+给sy讲明白(可能还没讲明白 具体思路是真的不想写了(快吐了 如果要看,参见洛谷P1600 天天爱跑步--题解 虽然这样不好但我真的不想写了 ...
- Memcached安装 常用指令
Memcached 源码安装 # 安装依赖yum install -y gcc gcc-c++ automake autoconf make cmake libevent-devel.x86_64# ...
- c语言:<tchar.h>
头文件“<tchar.h>”作用就是为了进行ASCII码和UNICODE(wide-character)码的头文件(该头文件由微软提供): 这样我们就可以使用TCHAR.H头文件中的定义的 ...
- 分布式锁的几种实现方法:redis实现分布式锁
使用失效的方式实现分布式锁(推荐) import redis.clients.jedis.Jedis; /** * 使用redis实现分布式锁(推荐) * */ public class JedLoc ...
- go build命令详解
原文地址讲解:https://blog.csdn.net/zl1zl2zl3/article/details/83374131
- deepin 15.10.1 GTX1060 NVIDIA 驱动安装,双屏显示问题记录
有一段时间没有用Linux了.由于买了个4k的戴尔显示屏,在deepin系统上无法用,从昨晚到现在,总于解决了我的问题! 问题1:无法直接在深度的显卡驱动管理器哪里直接切换,网上看到很多人都有这个问题 ...