[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 ...
随机推荐
- Activity LauchMode设置
lauchMode: standard: 标准模式,每次调用startActivity()方法就会产生一个新的实例. singleTop: 如果已经有一个实例位于Activit ...
- Android进阶——学习AccessibilityService实现微信抢红包插件
在你的手机更多设置或者高级设置中,我们会发现有个无障碍的功能,很多人不知道这个功能具体是干嘛的,其实这个功能是为了增强用户界面以帮助残障人士,或者可能暂时无法与设备充分交互的人们 它的具体实现是通过A ...
- JavaBean和json数据之间的转换(二)含有date类型的JavaBean
1.前言 上次讲了简单的JavaBean和json格式之间的转换,代码很简单,但是实际过程中,往往用到的JavaBean都是比较复杂的,其他的字段还好,如果JavaBean中包含了date类型的字段, ...
- c++程序—变量
#include<iostream> using namespace std; int main() { int a = 10; cout << "a=" ...
- html5有哪些新特性、移除了那些元素?
新增的元素: HTML5 现在已经不是 SGML 的子集,主要是关于图像,位置,存储,多任务等功能的增加. 拖拽释放(Drag and drop) API 语义化更好的内容标签(header,nav, ...
- python爬取招聘网站数据
# -*- coding: utf-8 -*- # 爬虫分析 from bs4 import BeautifulSoup from lxml import etree from selenium im ...
- Ubuntu Kylin 14.04LTS 开机后卡在登陆界面,可以进入字符界面,或者登陆后鼠标不显示但是管用
2014年4月27日,距离中期检查还有七天,基本上什么也没做,特别着急,雨已经下了快一天了,中午用美团外卖定的黄焖排骨,MD,什么玩意,那么一点点就18块钱,一看就不值五块钱,发誓再也不吃,最重要的是 ...
- 201709-2 公共钥匙盒 Java
思路: 按上课开始时间排一下序,一个时刻一个时刻判断要不要还钥匙,要不要借钥匙 import java.util.ArrayList; import java.util.Collections; im ...
- Nginx系列p1:安装
学习新的知识都要从搭建环境开始,今天我们就来学习搭建一个 Nginx 环境. 环境:Ubuntu16.04 STL Nginx 1.16.1 Stable version 前言:当然可以通过 apt- ...
- Django1.11基础视图
Django视图 路由命名与reverse反解析 在项目urls中的include函数,使用namespace参数定义路由命名空间 url(r'^',incude('book.urls',namesp ...