【树链剖分】【树状数组】【最近公共祖先】【块状树】bzoj3631 [JLOI2014]松鼠的新家
裸题,树状数组区间修改+单点查询。当然要稍微讨论一下链的左右端点是否修改的情况咯。
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define N 300001
int en,v[N<<1],first[N],next[N<<1],n;
void AddEdge(const int &U,const int &V)
{
v[++en]=V;
next[en]=first[U];
first[U]=en;
}
int dep[N],siz[N],fa[N],son[N],top[N],Num[N],tot;
void dfs(int U,int d)
{
dep[U]=d;
siz[U]=1;
for(int i=first[U];i;i=next[i])
if(v[i]!=fa[U])
{
fa[v[i]]=U;
dfs(v[i],d+1);
siz[U]+=siz[v[i]];
if(siz[v[i]]>siz[son[U]])
son[U]=v[i];
}
}
void dfs2(int U)
{
if(son[U])
{
top[son[U]]=top[U];
Num[son[U]]=++tot;
dfs2(son[U]);
}
for(int i=first[U];i;i=next[i])
if(v[i]!=fa[U]&&v[i]!=son[U])
{
top[v[i]]=v[i];
Num[v[i]]=++tot;
dfs2(v[i]);
}
}
int SIZ[N],TOP[N],sz;
void dfs3(int U)
{
for(int i=first[U];i;i=next[i])
if(v[i]!=fa[U])
{
if(SIZ[TOP[U]]<sz)
{
TOP[v[i]]=TOP[U];
++SIZ[TOP[U]];
}
dfs3(v[i]);
}
}
int lca(int U,int V)
{
while(U!=V)
{
if(TOP[U]!=TOP[V])
{
if(dep[TOP[U]]<dep[TOP[V]])
swap(U,V);
U=fa[TOP[U]];
}
else
{
if(dep[U]<dep[V])
swap(U,V);
U=fa[U];
}
}
return U;
}
int d[N];
void add_node(int p,const int &v){for(;p<=n;p+=(p&(-p))) d[p]+=v;}
void add_range(const int &L,const int &R){add_node(L,1);if(R!=n)add_node(R+1,-1);}
int query(int p){int res=0;for(;p;p-=(p&(-p)))res+=d[p];return res;}
void update(int U,int V)
{
int f1=top[U],f2=top[V];
while(f1!=f2)
{
if(dep[f1]<dep[f2])
{
swap(f1,f2);
swap(U,V);
}
add_range(Num[f1],Num[U]);
U=fa[f1];
f1=top[U];
}
if(dep[U]>dep[V])
swap(U,V);
add_range(Num[U],Num[V]);
}
int cnt,LL[N],RR[N];
void dfs4(int U)
{
LL[U]=++cnt;
for(int i=first[U];i;i=next[i])
if(v[i]!=fa[U])
dfs4(v[i]);
RR[U]=cnt;
}
int xu[N];
void work(const int &L,const int &R,const int &op)
{
if(op==n-1)
{
if(fa[L]==R||fa[R]==L) return;
int LCA=lca(L,R);
if(LCA==L)
{
for(int i=first[L];i;i=next[i])
if(v[i]!=fa[L]&&LL[R]>=LL[v[i]]&&LL[R]<=RR[v[i]])
{
update(v[i],fa[R]);
return;
}
}
else if(LCA==R)
{
for(int i=first[R];i;i=next[i])
if(v[i]!=fa[R]&&LL[L]>=LL[v[i]]&&LL[L]<=RR[v[i]])
{
update(fa[L],v[i]);
return;
}
}
else update(fa[L],fa[R]);
return;
}
if(lca(L,R)==L)
{
for(int i=first[L];i;i=next[i])
if(v[i]!=fa[L]&&LL[R]>=LL[v[i]]&&LL[R]<=RR[v[i]])
{
update(v[i],R);
return;
}
}
else update(fa[L],R);
}
int main()
{
int A,B;
scanf("%d",&n);
for(int i=1;i<=n;++i) scanf("%d",&xu[i]);
for(int i=1;i<n;++i)
{
scanf("%d%d",&A,&B);
AddEdge(A,B);
AddEdge(B,A);
}
top[1]=1;
Num[1]=++tot;
dfs(1,1);
dfs2(1);
sz=sqrt(n); if(!sz) sz=1;
for(int i=1;i<=n;i++)
{
SIZ[i]=1;
TOP[i]=i;
}
dfs3(1);
dfs4(1);
if(n==2)
{
work(xu[2],xu[1],0);
goto OUT;
}
update(xu[1],xu[2]);
for(int i=2;i<n;++i)
work(xu[i],xu[i+1],i);
OUT:for(int i=1;i<=n;++i)
printf("%d\n",query(Num[i]));
return 0;
}
【树链剖分】【树状数组】【最近公共祖先】【块状树】bzoj3631 [JLOI2014]松鼠的新家的更多相关文章
- [BZOJ3631][JLOI2014]松鼠的新家(树链剖分)
[BZOJ3631] 树剖模板题了, Code #include <cstdio> #include <algorithm> #define MID int mid=(l+r) ...
- 树链剖分的一种妙用与一类树链修改单点查询问题的时间复杂度优化——2018ACM陕西邀请赛J题
题目描述 有一棵树,每个结点有一个灯(初始均是关着的).每个灯能对该位置和相邻结点贡献1的亮度.现有两种操作: (1)将一条链上的灯状态翻转,开变关.关变开: (2)查询一个结点的亮度. 数据规模:\ ...
- BZOJ 3631: [JLOI2014]松鼠的新家( 树链剖分 )
裸树链剖分... ------------------------------------------------------------------- #include<bits/stdc++ ...
- 树链剖分 [JLOI2014]松鼠的新家
[JLOI2014]松鼠的新家 时间限制: 1 Sec 内存限制: 128 MB 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达, ...
- [JLOI2014]松鼠的新家(树链剖分)
[JLOI2014]松鼠的新家(luogu) Description 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家 树链剖分+差分前缀和优化
目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 说明 思路 AC代码 优化 优化后AC代码 总结 题面 题目链接 P3258 [JLOI2 ...
- Bzoj 3631: [JLOI2014]松鼠的新家(树链剖分+线段树)
3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MB Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个 ...
- [JLOI2014]松鼠的新家 (树剖)
题目 P3258 [JLOI2014]松鼠的新家 解析 非常裸的一道树剖题 链上修改+单点查询的板子 记录一下所经过的点\(now[i]\),每次更新\(now[i-1]到now[i]\) 我们链上更 ...
- 洛谷 P3258 [JLOI2014]松鼠的新家(树链剖分)
题目描述松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前来 ...
随机推荐
- HDU 5666 快速乘
Segment Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Sub ...
- 安卓tablayout控件的使用
1.加载依赖 api "com.android.support:design:26.1.0" 2.布局 <android.support.design.widget.TabL ...
- MySQL rpm 版本安装
准备: [root@localhost moudles]# ls MySQL-client-5.6.36-1.linux_glibc2.5.x86_64.rpm MySQL-server-5.6.3 ...
- CSS学习之float解析
转自:http://www.w3cplus.com/css/float.html 一.float是什么? float即为浮动,在CSS中的作用是使元素脱离正常的文档流并使其移动到其父元素的“最左边”或 ...
- java.lang.NumberFormatException: For input string: "26.0"
数据类型转化的时候的错误: 程序中要转的字符串不是一个数字,所以在format成数字的时候就出错了. 字符串不符合数字预定格式.
- Python阶段复习 - part 1 - Python基础练习题
1.实现1-100的所有的和 # 方法1: sum = 0 for i in range(1,101): sum += i print(sum) # 方法2: num1 = int(input('请输 ...
- Linux makefile 教程 非常详细,且易懂【转】
转自: http://blog.csdn.net/liang13664759/article/details/1771246 最近在学习Linux下的C编程,买了一本叫<Linux环境下的C ...
- (七)计算G711语音的打包长度和RTP里timestamp的增长量
如何计算G711语音等的打包长度和RTP里timestamp的增长量 一般对于不同的语音有不同的打包周期,而不同的打包周期又对应着不同的timestamp in RTP 那么是如何计算的呢,我们通过G ...
- Linux服务器中OpenSSH的源码编译与升级
Linux服务器中OpenSSH的源码编译与升级 https://www.oschina.net/question/12_7383
- Selenium2+python自动化60-异常后截图(screenshot)【转载】
前言 在执行用例过程中由于是无人值守的,用例运行报错的时候,我们希望能对当前屏幕截图,留下证据. 在写用例的时候,最后一步是断言,可以把截图的动作放在断言这里,那么如何在断言失败后截图呢? 一.截图方 ...