其实这道题其实可以转化为这样一个问题

给定n-1对点,将这两点x,y间简单路径上的点(包括起点终点)权值+1

(最后再把除了起点外的点的权值-1,注意终点没糖吃)

求每个点的权值

首先想到的是先找LCA然后暴力的对权值加,显然这样效率不够好

想到了树状数组完成区间修改和单点求值,是先将[l,r]中a[l]++,然后a[r+1]--;

这样就避免了对每个数都修改;

以此类推,我们可以假定路径使x-->root-->y上的点+1,

这样每个点的权值即为其所在子树和

设lca(x,y)=z 同样的道理,我们只要对a[x]++,a[y]++,然后对a[z]--,a[fa[z]]--

因为每个点的权值即为其所在子树和,所以只有x-->y的简单路径上的点权值+1了

这样的话我们可以做一遍LCA-tarjan就可以搞出来了(当然也可以再单独扫一遍)

 type node=record
po,next:longint;
can:boolean;
end; var a,q:array[..] of node;
fa,f,p,w,ans,g:array[..] of longint;
v:array[..] of boolean;
st,i,j,n,m,x,y,t:longint; function getf(x:longint):longint;
begin
if fa[x]<>x then fa[x]:=getf(fa[x]);
exit(fa[x]);
end; procedure addq(x,y:longint);
begin
inc(m);
q[m].po:=y;
q[m].next:=w[x];
w[x]:=m;
end; procedure add(x,y:longint);
begin
inc(t);
a[t].po:=y;
a[t].next:=p[x];
p[x]:=t;
end; procedure tarjan(x:longint);
var i,y,z:longint;
begin
i:=p[x];
v[x]:=true;
while i<> do
begin
y:=a[i].po;
if not v[y] then
begin
f[y]:=x;
tarjan(y);
fa[y]:=x;
end;
i:=a[i].next;
end;
i:=w[x];
while i<>- do
begin
y:=q[i].po;
if v[y] and not q[i].can then
begin
z:=getf(y);
q[i].can:=true;
q[i xor ].can:=true;
inc(g[z]);
inc(g[f[z]]);
end;
i:=q[i].next;
end;
ans[x]:=ans[x]-g[x];
ans[f[x]]:=ans[f[x]]+ans[x];//做到这已经说明x的子树已经被访问完了,x的权值已经确定,直接加即可,不需要再dfs一遍
end; begin
m:=-;
fillchar(w,sizeof(w),);
readln(n);
read(x);
st:=x;
ans[x]:=;
for i:= to n- do
begin
read(y);
addq(x,y);
addq(y,x);
inc(ans[y]);
if i<>n- then inc(ans[y]);
x:=y;
end;
for i:= to n- do
begin
readln(x,y);
add(x,y);
add(y,x);
end;
for i:= to n do
fa[i]:=i; tarjan();
for i:= to n do
begin
if i<>st then dec(ans[i]);
writeln(ans[i]);
end;
end.

bzoj3631的更多相关文章

  1. 【BZOJ3631】松树的新家 树链剖分

    BZOJ3631 松树的新家 Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...

  2. 【BZOJ3631】松鼠的新家 树链剖分

    BZOJ3631 松鼠的新家 Description 松鼠的新家是一棵树,前几天刚刚装修了新家,新家有n个房间,并且有n-1根树枝连接,每个房间都可以相互到达,且俩个房间之间的路线都是唯一的.天哪,他 ...

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

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

  4. bzoj3631树链剖分

    虽然是水题1A的感觉太爽了O(∩_∩)O~ 题意相当于n-1次树上路径上每个点权值+1,最后问每个点的权值 本来想写线段树,写好了change打算框架打完了再来补,结果打完发现只是区间加和单点查 前缀 ...

  5. bzoj3631: [JLOI2014]松鼠的新家(LCA+差分)

    题目大意:一棵树,以一定顺序走完n个点,求每个点经过多少遍 可以树链剖分,也可以直接在树上做差分序列的标记 后者打起来更舒适一点.. 具体实现: 先求x,y的lca,且dep[x]<dep[y] ...

  6. BZOJ3631: [JLOI2014]松鼠的新家

    传送门 树上的差分优化,很简单的一道题,应该属于NOIP2015TGD2T3的子问题. //BZOJ 3631 //by Cydiater //2016.10.25 #include <iost ...

  7. 【BZOJ-3631】松鼠的新家 树形DP?+ 倍增LCA + 打标记

    3631: [JLOI2014]松鼠的新家 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1231  Solved: 620[Submit][Stat ...

  8. 【bzoj3631】[JLOI2014]松鼠的新家

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

  9. BZOJ3631[JLOI2014]松鼠的新家 题解

    题目大意: 给你一棵树,要从编号为a[1]的节点走到编号为a[2]的节点再走到编号为a[3]的节点……一直走到编号为a[n]的节点.问每个节点最少访问多少次. 思路: 将其进行轻重链剖分,则从a[i] ...

随机推荐

  1. Android源码编译过程之九鼎开发板

    build_kernel() { # 进入源码顶层目录 cd ${BS_DIR_KERNEL} || # 编译配置文件 make ${BS_CONFIG_KERNEL} ARCH=arm CROSS_ ...

  2. Entity Framework Demo(一) 简单搭建环境

    Entity Framwork(实体框架,简称EF)是ORM(Object Relational Mapping,对象映射关系)的一个解决方案. EF允许项目将数据库的表映射为实体,并封装了操作方法, ...

  3. DedeCMS文章标题前增加所属栏目名称链接

    问题描述:在调用文章标题的时候,我想实现这样的形式:“[国内新闻]站长无忧真的是一个不错的站”,其中“国内新闻”是标题的所属栏目,并且加链接:    解决方法: [field:typelink /]这 ...

  4. C#中有关字符串去重的解决方案

    今天在群里看到一个同学的面试题 题目中有一个这样的要求 //本地有个文档文件a.txt里面包含的内容分为一段字符串"abacbacde"请编写一个程序,获取文件得到对应的内容,并对 ...

  5. [DEncrypt] Encrypt--加密/解密/MD5加密 (转载)

    点击下载  Encrypt.zip 这个类是关于加密,解密的操作,文件的一些高级操作1.Encrypt加密2.Encrypt解密3.Encrypt MD5加密看下面代码吧 /// <summar ...

  6. Andriod ADT v22.6.2版本中在Mainactivity.java中使用fragment_main.xml中TextView控件对象的问题

    众所周知,我们既可以在 activity_main.xml文件中控制activity中的view,也可以使用java代码的set..()方法控制它.在学习过程中,发现在ADT新版本中,和以前版本有区别 ...

  7. Oracel JDBC URL 和 Driver 的获取

    Driver 的获取 Driver Name:   oracle.jdbc.driver.OracleDriver Oracel JDBC URL的获取: URL:   jdbc:oracle:thi ...

  8. HDU 1114 Piggy-Bank(完全背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1114 题目大意:根据储钱罐的重量,求出里面钱最少有多少.给定储钱罐的初始重量,装硬币后重量,和每个对应 ...

  9. 倒置字符串s中各字符的位置

    倒置字符串s中各字符的位置 其中reverse函数可以写成更紧凑的形式 void reverse(char s[]){ int c,i,j; ,j=strlen(s)-;i<j;i++,j--) ...

  10. SGU 269. Rooks(DP)

    题意: 给n(<=250)条水平网格,然后在上面放k棋子,每行每列都只能放一个.求方法总数. Solution: 简单的DP, 只要对给出的水平长度排个序就很容易处理了. 需要用到高精度. 偷懒 ...