[ZJOI2019]语言(树链剖分+动态开点线段树+启发式合并)
首先,对于从每个点出发的路径,答案一定是过这个点的路径所覆盖的点数。然后可以做树上差分,对每个点记录路径产生总贡献,然后做一个树剖维护,对每个点维护一个动态开点线段树。最后再从根节点开始做一遍dfs,把每个节点对应的线段树启发式合并即可。时空复杂度均为O(nlog2n)。听说还有一个log的做法,但感觉太神仙不会,不过2个log能过就不管了。
#include<bits/stdc++.h>
#define lson l,mid,tr[rt].lc
#define rson mid+1,r,tr[rt].rc
using namespace std;
const int N=1e5+;
struct Seg{int lc,rc,tag,sz;}tr[N*];
int n,m,cnt,fa[N],sz[N],dep[N],son[N],top[N],dfn[N],rt[N];
long long ans;
vector<int>G[N];
void dfs1(int u,int f)
{
sz[u]=,dep[u]=dep[f]+,fa[u]=f;
for(int i=;i<G[u].size();i++)
if(G[u][i]!=f)
{
dfs1(G[u][i],u),sz[u]+=sz[G[u][i]];
if(sz[son[u]]<sz[G[u][i]])son[u]=G[u][i];
}
}
void dfs2(int u,int tp)
{
top[u]=tp,dfn[u]=++cnt;
if(son[u])dfs2(son[u],tp);
for(int i=;i<G[u].size();i++)if(G[u][i]!=fa[u]&&G[u][i]!=son[u])dfs2(G[u][i],G[u][i]);
}
void pushup(int rt,int len)
{if(tr[rt].tag)tr[rt].sz=len;else tr[rt].sz=tr[tr[rt].lc].sz+tr[tr[rt].rc].sz;}
void modify(int rt,int v,int len){tr[rt].tag+=v;pushup(rt,len);}
void update(int L,int R,int v,int l,int r,int&rt)
{
if(!rt)rt=++cnt;
if(L<=l&&r<=R){modify(rt,v,r-l+);return;}
int mid=l+r>>;
if(L<=mid)update(L,R,v,lson);
if(R>mid)update(L,R,v,rson);
pushup(rt,r-l+);
}
void Update(int&rt,int x,int y,int v)
{
while(top[x]!=top[y])update(dfn[top[x]],dfn[x],v,,n,rt),x=fa[top[x]];
if(x!=y)update(dfn[y]+,dfn[x],v,,n,rt);
}
int lca(int x,int y)
{
while(top[x]!=top[y])if(dep[top[x]]<dep[top[y]])y=fa[top[y]];else x=fa[top[x]];
return dep[x]<dep[y]?x:y;
}
int merge(int u,int v,int l,int r)
{
if(!u||!v)return u+v;
tr[u].tag+=tr[v].tag;
if(l==r){pushup(u,);return u;}
int mid=l+r>>;
tr[u].lc=merge(tr[u].lc,tr[v].lc,l,mid);
tr[u].rc=merge(tr[u].rc,tr[v].rc,mid+,r);
pushup(u,r-l+);
return u;
}
void dfs3(int u,int f)
{
for(int i=;i<G[u].size();i++)
if(G[u][i]!=f)dfs3(G[u][i],u),rt[u]=merge(rt[u],rt[G[u][i]],,n);
ans+=max(tr[rt[u]].sz-,);
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=,x,y;i<n;i++)scanf("%d%d",&x,&y),G[x].push_back(y),G[y].push_back(x);
dfs1(,);
dfs2(,);
cnt=;
for(int i=,x,y,f;i<=m;i++)
{
scanf("%d%d",&x,&y);
f=lca(x,y);
Update(rt[x],x,fa[f],),Update(rt[x],y,f,);
Update(rt[y],x,fa[f],),Update(rt[y],y,f,);
Update(rt[f],x,fa[f],-),Update(rt[f],y,f,-);
if(fa[f])Update(rt[fa[f]],x,fa[f],-),Update(rt[fa[f]],y,f,-);
}
dfs3(,);
cout<<ans/;
}
[ZJOI2019]语言(树链剖分+动态开点线段树+启发式合并)的更多相关文章
- 【bzoj4999】This Problem Is Too Simple! 树链剖分+动态开点线段树
题目描述 给您一颗树,每个节点有个初始值. 现在支持以下两种操作: 1. C i x(0<=x<2^31) 表示将i节点的值改为x. 2. Q i j x(0<=x<2^31) ...
- [bzoj 3531][SDOI2014]旅行(树链剖分+动态开点线段树)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3531 分析: 对于每个颜色(颜色<=10^5)都建立一颗线段树 什么!那么不是M ...
- 洛谷P3313 [SDOI2014]旅行(树链剖分 动态开节点线段树)
题意 题目链接 Sol 树链剖分板子 + 动态开节点线段树板子 #include<bits/stdc++.h> #define Pair pair<int, int> #def ...
- BZOJ 3531 [Sdoi2014]旅行 树链剖分+动态开点线段树
题意 S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天面条神教.隐形独角兽教.绝地教都是常见的信仰. 为了方便,我们用 ...
- bzoj3531: [Sdoi2014]旅行 (树链剖分 && 动态开点线段树)
感觉动态开点线段树空间复杂度好优秀呀 树剖裸题 把每个宗教都开一颗线段树就可以了 但是我一直TLE 然后调了一个小时 为什么呢 因为我 #define max(x, y) (x > y ? x ...
- 【BZOJ3531】[Sdoi2014]旅行 树链剖分+动态开点线段树
[BZOJ3531][Sdoi2014]旅行 Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连接,满足从一个城市出发可以到达其它所有城市.每个城市信仰不同的宗教,如飞天 ...
- BZOJ4999: This Problem Is Too Simple!树链剖分+动态开点线段树
题目大意:将某个节点的颜色变为x,查询i,j路径上多少个颜色为x的点... 其实最开始一看就是主席树+树状数组+DFS序...但是过不去...MLE+TLE BY FCWWW 其实树剖裸的一批...只 ...
- bzoj3531——树链剖分+动态开点线段树
3531: [Sdoi2014]旅行 Time Limit: 20 Sec Memory Limit: 512 MB Description S国有N个城市,编号从1到N.城市间用N-1条双向道路连 ...
- [LuoguU41039]PION后缀自动机 树链剖分+动态开点线段树
链接 刚开始看出题人题解都吓蒙掉了,还以为是什么难题,结果就一板子题 思路:对每一个文件名开一棵线段树,然后树剖即可 #include<bits/stdc++.h> #define REP ...
随机推荐
- C++命名规范——谷歌规范
1.文件命名规则 文件名全部小写,可以含下划线或连字符,按项目约定命名,且尽量保证文件名明确.比如: cmd_save_player_info_class.cc ,my_use_full_class. ...
- argv从控制台输入多个参数
arg多个参数: #!/usr/bin/env python3 import sys #控制台要输入的两个参数格式为:python script_name.py 参数1 参数2 input_file= ...
- SASS - 输出格式
SASS – 简介 SASS – 环境搭建 SASS – 使用Sass程序 SASS – 语法 SASS – 变量 SASS- 局部文件(Partial) SASS – 混合(Mixin) SASS ...
- SASS - 函数
SASS – 简介 SASS – 环境搭建 SASS – 使用Sass程序 SASS – 语法 SASS – 变量 SASS- 局部文件(Partial) SASS – 混合(Mixin) SASS ...
- HashMap源码阅读笔记
HashMap源码阅读笔记 本文在此博客的内容上进行了部分修改,旨在加深笔者对HashMap的理解,暂不讨论红黑树相关逻辑 概述 HashMap作为经常使用到的类,大多时候都是只知道大概原理,比如 ...
- CountDownLatch和CyclicBarrier和Semaphore最通俗形象解释
应该还有好多同学对这三个的区别比较模糊,网络上其他文章说的也比较专业化.所以我在这里举个例子说明这三个的区别. 我们假定有一场百米比赛,比赛包括十个运动员和一个裁判,每个运动员和每个裁判都是一个线程, ...
- 18 12 `12 WSGI 协议
所谓wsig 协议 就是把web框架 和服务器进行分开 然后通过 wisg协议 进行连接 这样子可以随时替换web框架 或者 更换服务器 解耦 (现在学的内容里 静态连接一般是放在服务器里 ...
- 个人安装GO1.13.6版本指南手册之搭建环境
因好奇而走进go语言,让你不在只闻其声,不见其形. https://golang.org/doc/install:这里是go语言的官网文档.吃不透英文,终究会被限制在有限的区域,一词词的吃透. 安装包 ...
- Microsoft SQL server Management Studio工具报错“应用程序的组件中发生了无法处理的异常”
解决办法 打开目录: C:\Documents and Settings\Administrator\Application Data\Microsoft\Microsoft SQL Server\1 ...
- MySQL各种存储引擎对比总结
1.MyISAM 是MySQL5.5版之前默认的存储引擎,特点:数据文件和索引文件可以放置在不同的目录,平局分布IO,获得更快的速度.不支持事务,不支持外键. 2.InnoDB 是 MySQL5.5版 ...