Description

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

Input

第1行包含一个整数N。
接下来N-1行,每行包含三个整数a_i、b_i和t_i,表示这条路上药材的类型。

Output

输出符合采药人要求的路径数目。

Sample Input

7
1 2 0
3 1 1
2 4 0
5 2 0
6 3 1
5 7 1

Sample Output

1

Solution

我可能学了假的点分治……
用g[i][0…1],f[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为当前子树的深度。

Code

 #include<iostream>
#include<cstring>
#include<cstdio>
#define N (200000+100)
using namespace std;
struct node
{
int to,next,len;
} edge[N*];
int n,k,sum,root,INF;
long long ans,g[N][],f[N][];
int t[N*];
int head[N],num_edge,max_depth;
int depth[N],d[N],size[N],maxn[N],dis[N];
bool vis[N]; void add(int u,int v,int l)
{
edge[++num_edge].to=v;
edge[num_edge].len=l;
edge[num_edge].next=head[u];
head[u]=num_edge;
} void Get_root(int x,int fa)
{
size[x]=;
maxn[x]=;
for (int i=head[x]; i!=; i=edge[i].next)
if (!vis[edge[i].to] && edge[i].to!=fa)
{
Get_root(edge[i].to,x);
size[x]+=size[edge[i].to];
maxn[x]=max(maxn[x],size[edge[i].to]);
}
maxn[x]=max(maxn[x],sum-size[x]);
if (maxn[x]<maxn[root]) root=x;
} void Calc(int x,int fa)
{
max_depth=max(max_depth,depth[x]);
if (t[dis[x]]) f[dis[x]][]++;
else f[dis[x]][]++;
t[dis[x]]++;
for (int i=head[x]; i!=; i=edge[i].next)
if (edge[i].to!=fa && !vis[edge[i].to])
{
depth[edge[i].to]=depth[x]+;
dis[edge[i].to]=dis[x]+edge[i].len;
Calc(edge[i].to,x);
}
t[dis[x]]--;
} void Solve(int x)
{
vis[x]=true;
g[n][]=;//关于这里为什么初始化为1的问题,想了好久,最后还是学姐给我的解答
//http://blog.csdn.net/wu_tongtong/article/details/79428928
//可能路径是从当前树根到某一个节点的时候,路径已经平衡,不需要去另一个子树里面找另一个链拼接了
//所以这一部分的答案也要统计进去。
int up=;
for (int i=head[x]; i!=; i=edge[i].next)
if (!vis[edge[i].to])
{
depth[edge[i].to]=;
dis[edge[i].to]=edge[i].len+n;
max_depth=;
Calc(edge[i].to,);
up=max(up,max_depth); ans+=(g[n][]-)*f[n][];
for (int j=-max_depth; j<=max_depth; ++j)
ans+=g[n-j][]*f[n+j][]+g[n-j][]*f[n+j][]+g[n-j][]*f[n+j][];
for (int j=-max_depth; j<=max_depth; ++j)
{
g[n-j][]+=f[n-j][];
g[n-j][]+=f[n-j][];
f[n-j][]=f[n-j][]=;
}
}
for (int i=-up; i<=up; ++i)
g[n-i][]=g[n-i][]=;
for (int i=head[x]; i!=; i=edge[i].next)
if (!vis[edge[i].to])
{
sum=size[edge[i].to];
root=;
Get_root(edge[i].to,);
Solve(root);
}
} int main()
{
int u,v,l;
scanf("%d",&n);
sum=maxn[]=n;
for (int i=; i<=n-; ++i)
{
scanf("%d%d%d",&u,&v,&l);
add(u,v,l==?-:);
add(v,u,l==?-:);
}
Get_root(,);
Solve(root);
printf("%lld",ans);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用

    使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(一)——创建应用 使用 Flask 框架写用户登录功能的Demo时碰到的各种坑(二)——使用蓝图功能进行模块化 使用 Flask 框架写用 ...

  2. Java - 使可访问性最小化

    模块设计是否良好,有个重要的因素在于,相对外部模块是否隐藏内部数据以及实现细节. 设计良好的模块会隐藏实现细节,并将API与其实现隔离开来. 模块之间通过API进行通信,对于内部工作情况互不可见. 即 ...

  3. Cheatsheet: 2018 11.01 ~ 2019 02.28

    Golang FromXToGo micro - A microservice toolkit Other Easy parsing of Excel spreadsheet format with ...

  4. [javaEE] response实现图片下载

    在Servlet中的doGet()方法中 获取FileInputStream对象,new出来,构造参数:String的文件路径 得到文件路径,调用this.getServletContext().ge ...

  5. Java学习--java中的集合框架、Collection接口、list接口

    与数组相比:1.数组的长度固定,而集合的长度可变2.数组只能通过下表访问元素,类型固定,而有的集合可以通过任意类型查找所映射的具体对象 java集合框架:collection(list序列,queue ...

  6. CentOS添加SSH登录提示

    前言 使用阿里云服务器的应该都注意到每次ssh登录后都能看见类似下面这样的欢迎语: Last login:xxxxxxxxxxxxx Welcome to Alibaba Cloud Elastic ...

  7. BZOJ4903: [Ctsc2017]吉夫特

    传送门 可以发现,\(\binom{n}{m}\equiv 1(mod~2)\) 当且仅当 \(m~and~n~=~m\) 即 \(m\) 二进制下为 \(n\) 的子集 那么可以直接写一个 \(3^ ...

  8. Java设计模式—命令模式

    命令模式是一个高内聚的模式. 定义如下:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能. 通用类图如下: 角色说明: ● Re ...

  9. baidu地图api , 地理位置转 经纬度接口

    更多可以查看    http://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-geocoding 地理编码示例: 以下是关于地理编 ...

  10. 图片(imageView)

    图片(imageView): 常用属性: android:scaleType(图片显示的格式) android:src(图片源,一般使用的资源) android:scaleType属性的常用取值 0. ...