裸题,树状数组区间修改+单点查询。当然要稍微讨论一下链的左右端点是否修改的情况咯。

#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]松鼠的新家的更多相关文章

  1. [BZOJ3631][JLOI2014]松鼠的新家(树链剖分)

    [BZOJ3631] 树剖模板题了, Code #include <cstdio> #include <algorithm> #define MID int mid=(l+r) ...

  2. 树链剖分的一种妙用与一类树链修改单点查询问题的时间复杂度优化——2018ACM陕西邀请赛J题

    题目描述 有一棵树,每个结点有一个灯(初始均是关着的).每个灯能对该位置和相邻结点贡献1的亮度.现有两种操作: (1)将一条链上的灯状态翻转,开变关.关变开: (2)查询一个结点的亮度. 数据规模:\ ...

  3. BZOJ 3631: [JLOI2014]松鼠的新家( 树链剖分 )

    裸树链剖分... ------------------------------------------------------------------- #include<bits/stdc++ ...

  4. 树链剖分 [JLOI2014]松鼠的新家

    [JLOI2014]松鼠的新家 时间限制: 1 Sec  内存限制: 128 MB 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达, ...

  5. [JLOI2014]松鼠的新家(树链剖分)

    [JLOI2014]松鼠的新家(luogu) Description 题目描述 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间 ...

  6. 洛谷 P3258 [JLOI2014]松鼠的新家 树链剖分+差分前缀和优化

    目录 题面 题目链接 题目描述 输入输出格式 输入格式 输出格式 输入输出样例 输入样例: 输出样例: 说明 说明 思路 AC代码 优化 优化后AC代码 总结 题面 题目链接 P3258 [JLOI2 ...

  7. Bzoj 3631: [JLOI2014]松鼠的新家(树链剖分+线段树)

    3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec Memory Limit: 128 MB Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个 ...

  8. [JLOI2014]松鼠的新家 (树剖)

    题目 P3258 [JLOI2014]松鼠的新家 解析 非常裸的一道树剖题 链上修改+单点查询的板子 记录一下所经过的点\(now[i]\),每次更新\(now[i-1]到now[i]\) 我们链上更 ...

  9. 洛谷 P3258 [JLOI2014]松鼠的新家(树链剖分)

    题目描述松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他居然真的住在”树“上. 松鼠想邀请小熊维尼前来 ...

随机推荐

  1. 解决导出为Excel时文件名乱码的问题。

    以前代码:public static void htmlToExcel(HttpContext context, string title, string html, string fileCss = ...

  2. POJ2492:A Bug's Life(种类并查集)

    A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 45757   Accepted: 14757 题 ...

  3. jsonp应用

    1.服务端jsonp格式数据 如客户想访问 : http://www.runoob.com/try/ajax/jsonp.php?jsonp=callbackFunction. 假设客户期望返回JSO ...

  4. Restful 接口权限控制

    前言 有人说,每个人都是平等的: 也有人说,人生来就是不平等的: 在人类社会中,并没有绝对的公平, 一件事,并不是所有人都能去做: 一样物,并不是所有人都能够拥有. 每个人都有自己的角色,每种角色都有 ...

  5. struts2和jstl有关循环的写法

    一:前言 其实觉得自己现在就是个码农啊,对于struts2的标签和jstl的标签我一直都是只会用,但是觉得自己老是会混淆这种概念性的问题.所以我自己在代码里面就试着用了几种方式,实现同一种效果,下面就 ...

  6. codevs1163访问艺术馆 树形dp

    算裸的树形dp吧 回来复习一波 #include<cstdio> #include<cstring> #include<algorithm> #include< ...

  7. CCCC练习即感

    字符串进行初始化时不能通过char a[10]={'\0'}来简单进行,写循环或者memset,亲测有效,以及初始化分好情况,用空格还是'\0',别乱搞. 有一个有意思的题,连续因子,从2开始,依次向 ...

  8. 在Xcode5下实现4.5,4.6的效果

      https://www.evernote.com/shard/s227/sh/a575caee-d6a8-4f43-9037-145b9a6913ca/c9a2befa22ce7c3f547f58 ...

  9. 正则表达式 re模块 collections模块

    根据手机号码一共11位并且是只以13.14.15.18开头的数字这些特点,我们用python写了如下代码: while True: phone_number = input('please input ...

  10. 哪些情况会导致OOM

    1. 堆溢出 java堆用于存储对象实例,只要不断地创建对象,并且这些对象不会被回收(什么情况对象不会被回收呢?如:由于GC Root到对象之间有可达路径,所以垃圾回收机制不会清除这些对象),那么,当 ...