题意:采药人的药田是一个树状结构,每条路径上都种植着同种药材。
采药人以自己对药材独到的见解,对每种药材进行了分类。大致分为两类,一种是阴性的,一种是阳性的。
采药人每天都要进行采药活动。他选择的路径是很有讲究的,他认为阴阳平衡是很重要的,所以他走的一定是两种药材数目相等的路径。采药工作是很辛苦的,所以他希望他选出的路径中有一个可以作为休息站的节点(不包括起点和终点),满足起点到休息站和休息站到终点的路径也是阴阳平衡的。他想知道他一共可以选择多少种不同的路径。

n<=100000

思路:RYZ作业

From hzwer:

来自出题人hta的题解。。

本题可以考虑树的点分治。问题就变成求过根满足条件的路径数。

路径上的休息站一定是在起点到根的路径上,或者根到终点的路径上。

如何判断一条从根出发的路径是否包含休息站?只要在dfs中记录下这条路径的和x,同时用个标志数组判断这条路径是否存在前缀和为x的节点。

这样我们枚举根节点的每个子树。用f[i][0…1],g[i][0…1]分别表示前面几个子树以及当前子树和为i的路径数目,0和1用于区分路径上是否存在前缀和为i的节点。那么当前子树的贡献就是f[0][0] * g[0][0] + Σf [i][0] * g [-i][1] + f[i][1] * g[-i][0] + f[i][1] * g[-i][1],其中i的范围[-d,d],d为当前子树的深度。

 var head,vet,next,len,d,dis,son,flag,dep:array[..]of longint;
c:array[..]of longint;
b:array[-..]of longint;
f,g:array[-..,..]of int64;
n,m,i,x,y,z,tot,sum,root,mxdep:longint;
ans:int64; procedure add(a,b,c:longint);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len[tot]:=c;
head[a]:=tot;
end; function max(x,y:longint):longint;
begin
if x>y then exit(x);
exit(y);
end; procedure getroot(u,fa:longint);
var e,v:longint;
begin
son[u]:=; c[u]:=;
e:=head[u];
while e<> do
begin
v:=vet[e];
if (v<>fa)and(flag[v]=) then
begin
getroot(v,u);
son[u]:=son[u]+son[v];
c[u]:=max(c[u],son[v]);
end;
e:=next[e];
end;
c[u]:=max(c[u],sum-c[u]);
if c[u]<c[root] then root:=u;
end; procedure dfs(u,fa:longint);
var e,v:longint;
begin
mxdep:=max(mxdep,dep[u]);
if b[dis[u]]> then inc(f[dis[u],])
else inc(f[dis[u],]);
inc(b[dis[u]]);
e:=head[u];
while e<> do
begin
v:=vet[e];
if (v<>fa)and(flag[v]=) then
begin
dep[v]:=dep[u]+;
dis[v]:=dis[u]+len[e];
dfs(v,u);
end;
e:=next[e];
end;
dec(b[dis[u]]);
end; procedure solve(u:longint);
var e,v,i,mx:longint;
begin
mx:=;
flag[u]:=; g[,]:=;
e:=head[u];
while e<> do
begin
v:=vet[e];
if flag[v]= then
begin
dis[v]:=len[e];
dep[v]:=; mxdep:=;
dfs(v,u);
mx:=max(mx,mxdep);
ans:=ans+(g[,]-)*f[,];
for i:=-mxdep to mxdep do
ans:=ans+g[-i,]*f[i,]+g[-i,]*f[i,]+g[-i,]*f[i,];
for i:=-mxdep to mxdep do
begin
g[i,]:=g[i,]+f[i,];
g[i,]:=g[i,]+f[i,];
f[i,]:=; f[i,]:=;
end;
end;
e:=next[e];
end;
for i:=-mx to mx do
begin
g[i,]:=; g[i,]:=;
end;
e:=head[u];
while e<> do
begin
v:=vet[e];
if flag[v]= then
begin
sum:=son[v]; root:=;
getroot(v,);
solve(root);
end;
e:=next[e];
end;
end; begin
assign(input,'bzoj3697.in'); reset(input);
assign(output,'bzoj3697.out'); rewrite(output);
readln(n);
for i:= to n- do
begin
readln(x,y,z);
if z= then z:=-;
add(x,y,z);
add(y,x,z);
end;
root:=; sum:=n; c[]:=n;
getroot(,);
solve(root);
writeln(ans);
close(input);
close(output);
end.

【BZOJ3697】采药人的路径(点分治)的更多相关文章

  1. BZOJ3697采药人的路径——点分治

    题目描述 采药人的药田是一个树状结构,每条路径上都种植着同种药材.采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是阳性的.采药人每天都要进行采药活动.他选择的路径 ...

  2. BZOJ3697:采药人的路径(点分治)

    Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材. 采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是阳性的. 采药人每天都要进行采药 ...

  3. [bzoj3697]采药人的路径——点分治

    Brief Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材. 采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是阳性的. 采药人每天 ...

  4. 【BZOJ3697】采药人的路径 点分治

    [BZOJ3697]采药人的路径 Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材.采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是 ...

  5. [bzoj3697]采药人的路径_点分治

    采药人的路径 bzoj-3697 题目大意:给你一个n个节点的树,每条边分为阴性和阳性,求满足条件的链的个数,使得这条链上阴性的边的条数等于阳性的边的条数,且这条链上存在一个节点,这个节点到一个端点的 ...

  6. bzoj千题计划248:bzoj3697: 采药人的路径

    http://www.lydsy.com/JudgeOnline/problem.php?id=3697 点分治 路径0改为路径-1 g[i][0/1] 和 f[i][0/1]分别表示当前子树 和 已 ...

  7. BZOJ3697 采药人的路径 【点分治】

    题目 采药人的药田是一个树状结构,每条路径上都种植着同种药材. 采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是阳性的. 采药人每天都要进行采药活动.他选择的路径 ...

  8. BZOJ3697: 采药人的路径(点分治)

    Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材.采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是阳性的.采药人每天都要进行采药活动 ...

  9. 2019.01.09 bzoj3697: 采药人的路径(点分治)

    传送门 点分治好题. 题意:给出一棵树,边分两种,求满足由两条两种边数相等的路径拼成的路径数. 思路: 考虑将边的种类转化成边权−1-1−1和111,这样就只用考虑由两条权值为000的路径拼成的路径数 ...

  10. BZOJ 3697/3127 采药人的路径 (点分治)

    题目大意: 从前有一棵无向树,树上边权均为$0$或$1$,有一个采药人,他认为如果一条路径上边权为$0$和$1$的边数量相等,那么这条路径阴阳平衡.他想寻找一条合法的采药路径,保证阴阳平衡.然后他发现 ...

随机推荐

  1. HUST 1698 - 电影院 组合数学 + 分类思想

    http://acm.hust.edu.cn/problem/show/1698 题目就是要把一个数n分成4段,其中中间两段一定要是奇数. 问有多少种情况. 分类, 奇数 + 奇数 + 奇数 + 奇数 ...

  2. 基于Ubuntu14.04下Suricata(一款高性能的网络IDS、IPS和网络安全监控引擎)的搭建(图文详解)(博主推荐)

    为什么,要写这篇论文? 是因为,目前科研的我,正值研三,致力于网络安全.大数据.机器学习研究领域! 论文方向的需要,同时不局限于真实物理环境机器实验室的攻防环境.也不局限于真实物理机器环境实验室的大数 ...

  3. [转]windows azure How to use Blob storage from .NET

    本文转自:http://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-blobs/?rnd=1 ...

  4. AJPFX关于modifier总结

    修饰符总结 Modifiers        函数修饰符始终在返回值类型之前!!!        变量修饰符始终在变量类型之前!!!---------------------------------- ...

  5. C#过时方法标记

    1.当遇到过时或废弃的方式 函数怎么办 [Obsolete]特性解决你的困惑 1.1:当方法已经完成相关兼容 可以保留时

  6. rabbitmq在storm中使用

    storm中只能进行任务计算,不能保存中间结果,最后结果. 这就有一个需求,保存计算结果,最好还是分布式的,因为storm也是分布式,大数据计算. 流行的分布式计算中使用队列保存数据居多. kafka ...

  7. Node.js——npm

    npm un 包名 :删除指定包,不删除安装的依赖 npm un --save 包名: 删除包,并且删除其依赖项 npm install -g cnpm --registry=https://regi ...

  8. chatops--rocketchat+hubot

    chatops--rocketchat+hubot 原文地址:http://www.cnblogs.com/caoguo/p/7221956.html 先放几张图 # rocket.chat # hu ...

  9. python照相机模型与增强现实

    这次试验主要实现以平面和标记物进行姿态估计以及增强现实的应用. 一.以平面和标记物进行姿态估计(1)下面演示的是一个简单例子:如何在一副图像上放置一个立方体,原图如下: (2)先提取两幅JPG图像的S ...

  10. 编写高质量Python代码的59个有效方法

    Python学习资料或者需要代码.视频加Python学习群:960410445 1. 用Pythonic方式思考 第一条:确认自己使用的Python版本 (1)有两个版本的python处于活跃状态,p ...