3697: 采药人的路径

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit:
681  Solved: 246
[Submit][Status][Discuss]

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

HINT

对于100%的数据,N ≤ 100,000。

Source

3127: [Usaco2013 Open]Yin and Yang

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 116  Solved: 82
[Submit][Status][Discuss]

Description

Farns (1 <= N <= 100,000) which are connected by N-1 edges such that
he can reach any barn from any other. Farmer John wants to choose a path which starts and ends at two
different barns, such that he does not traverse any edge twice. He worries that his path might be a
little long, so he also wants to choose another "rest stop" barn located on this path (which is distinct
from the start or the end). Along each edge is a herd of cows, either of the Charcolais (white hair)
or the Angus (black hair) variety. Being the wise man that he is, Farmer John wants to balance the
forces of yin and yang that weigh upon his walk. To do so, he wishes to choose a path such that he
will pass by an equal number of Charcolais herds and Angus herds-- oth on the way from the start to
his rest stop, and on theway from the rest stop to the end. Farmer John is curious how many different
paths he can choose that  are "balanced" as described above. Two paths are different only if they
consist of different setsof edges; a path should be counted only once even if there are multiple valid
"rest stop" locationsalong the path that make it balanced. Please help determine the number of
paths Farmer John can cho

Input

* Line 1: The integer N.
* Lines 2..N: Three integers a_i, b_i and t_i, representing the two barns
that edge i connects. t_i 
is 0 if the herd along that edge is Charcolais, and 1 if the herd is
Angus.

Output

Line 1: One integer, representing the number of possible paths Farmer John
can choose from.

Sample Input

7
1 2 0
3 1 1
2 4 0
5 2
0
6 3 1
5 7 1
INPUT DETAILS:
There are 7 barns and 6 edges. The
edges from 1 to 2, 2 to 4 and 2 to 5 have Charcolais herds along

them.

Sample Output

1
OUTPUT DETAILS:
No path of
length 2 can have a suitable rest stop on it, so we can only consider paths of
length 4.
The only path that has a suitable rest stop is 3-1-2-5-7, with a
rest stop at 2.

HINT

Source

Gold

Solution

这道题有点厉害

首先肯定想到点分治,问题在于如何统计答案

首先对于阴阳边,我们可以赋权值+1/-1,这样路径阴阳数目就比较直观了

定义$f[i][0/1]$表示当前子树中路径和为$i$的路径个数,0/1表示路径上是否存在前缀为$i$的点

定义$g[i][0/1]$表示之前前子树中路径和为$i$的路径个数,0/1同理

那么对答案的贡献就是$g[0][0]*f[0][0]+\sum (g[-i][0]]*f[i][1]+g[-i][1]*f[i][0]+g[-i][1]*f[i][1])$

要注意考虑下标为负的情况...全部+N即可

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int read()
{
int x=,f=; char ch=getchar();
while (ch<'' || ch>'') {if (ch=='-') f=-; ch=getchar();}
while (ch>='' && ch<='') {x=x*+ch-''; ch=getchar();}
return x*f;
}
#define MAXN 100010
#define LL long long
int N;
struct EdgeNode{int next,to,val;}edge[MAXN<<];
int head[MAXN],cnt=;
void AddEdge(int u,int v,int w) {cnt++; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].to=v; edge[cnt].val=w;}
void InsertEdge(int u,int v,int w) {AddEdge(u,v,w); AddEdge(v,u,w);}
int size[MAXN],maxx[MAXN],root,Sz; bool visit[MAXN];
void DFSRoot(int now,int last)
{
size[now]=; maxx[now]=;
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].to!=last && !visit[edge[i].to])
{
DFSRoot(edge[i].to,now);
size[now]+=size[edge[i].to];
maxx[now]=max(maxx[now],size[edge[i].to]);
}
maxx[now]=max(maxx[now],Sz-size[now]);
if (maxx[now]<maxx[root]) root=now;
}
int deep[MAXN],maxd,md,mark[MAXN<<],D[MAXN<<];
LL f[MAXN<<][],g[MAXN<<][],ans;
void DFS(int now,int last)
{
maxd=max(maxd,deep[now]);
if (mark[D[now]]) f[D[now]][]++; else f[D[now]][]++;
mark[D[now]]++;
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].to!=last && !visit[edge[i].to])
{
deep[edge[i].to]=deep[now]+;
D[edge[i].to]=D[now]+edge[i].val;
DFS(edge[i].to,now);
}
mark[D[now]]--;
}
void Get(int x,int val)
{
D[x]=N+val; deep[x]=;
maxd=; DFS(x,); md=max(maxd,md);
ans+=(g[N][]-)*f[N][];
for (int i=-maxd; i<=maxd; i++)
ans+=g[N-i][]*f[N+i][]+g[N-i][]*f[N+i][]+g[N-i][]*f[N+i][];
for (int i=N-maxd; i<=N+maxd; i++)
g[i][]+=f[i][],g[i][]+=f[i][],f[i][]=f[i][]=;
}
void Divide(int x)
{
visit[x]=;
g[N][]=; md=;
for (int i=head[x]; i; i=edge[i].next)
if (!visit[edge[i].to]) Get(edge[i].to,edge[i].val);
for (int i=-md; i<=md; i++) g[N+i][]=g[N+i][]=;
for (int i=head[x]; i; i=edge[i].next)
if (!visit[edge[i].to])
{
Sz=size[edge[i].to]; root=;
DFSRoot(edge[i].to,x);
Divide(root);
}
}
int main()
{
N=read();
for (int x,y,z,i=; i<=N-; i++)
x=read(),y=read(),z=read(),InsertEdge(x,y,z? z:-);
Sz=maxx[root=]=N;
DFSRoot(,);
Divide(root);
printf("%lld\n",ans);
return ;
}

【BZOJ-3697&3127】采药人的路径&YinandYang 点分治 + 乱搞的更多相关文章

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

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

  2. 【BZOJ 3697】采药人的路径

    题目链接: TP 题解: 调了好久233. 大概想一想就是树分,然后考虑这样路径(u,v)的特征,以根节点(root)切开,u到root的阴阳差值,和v到root巧合互为相反数,然后考虑要有一个点可作 ...

  3. BZOJ_3697_采药人的路径_点分治

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

  4. 【BZOJ】【3697】采药人的路径&【3127】【USACO2013 Open】Yin and Yang

    点分治 Orz hzwer 倒是比较好想到点分治……然而在方案统计这里,我犯了两个错误…… 1.我比较傻逼的想的是:通过儿子来更新父亲,也就是统计以x为根的子树中xxxx的路径有多少条……这样转移. ...

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

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

  6. bzoj 3697: 采药人的路径【点分治】

    点分治,设当前处理的块的重心为rt,预处理出每个子树中f[v][0/1]表示组合出.没组合出一对值v的链数(从当前儿子出发的链),能组合出一对v值就是可以有一个休息点 然后对于rt,经过rt且合法的路 ...

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

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

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

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

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

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

随机推荐

  1. SPM paired t-test步骤

    首先感谢大神空里流霜耐心的讲解,这篇笔记内容主要是整理他的谆谆教导,虽然他也看不到>< 所有数据都要经过平滑. Paired t-test虽然在2nd-level analysis中,但是 ...

  2. SQL80001: Incorrect syntax near ':'

    原文连接:http://geekswithblogs.net/tonyt/archive/2010/03/05/138363.aspx   SQL80001: Incorrect syntax nea ...

  3. Elasticsearch-2.3.x填坑之路

    使用版本说明:2.3.2 强制不能使用root用户启动?因为在2.x版本强调了安全性,防止attracker侵入root用户,所以建议使用者创建其他用户启动.当然,可以通过配置来实现root用户启动. ...

  4. 获取iframe加载完毕事件

    function IframeLoad(o,fn) { if (document.all) { o.attachEvent('onload', fn); } else { o.onload = fn; ...

  5. c#:Reflector+Reflexil 修改编译后的dll/exe文件

    不知道大家有没有这样的经历:现场实施时测试出一个bug,明明知道某个dll/exe文件只要修改一二行代码即可,但手头没有开发环境,紧急情况下,可以用reflector + reflexil 临时直接修 ...

  6. Java面试知识点总结

    本篇文章会对面试中常遇到的Java技术点进行全面深入的总结,帮助我们在面试中更加得心应手,不参加面试的同学也能够借此机会梳理一下自己的知识体系,进行查漏补缺(阅读本文需要有一定的Java基础:若您初涉 ...

  7. APP架子迁移指南(二)

    接上一篇,这一篇开始用android来解释MVP概念.八股式的架子结构和命名规范.我在准备这篇文章的时候还看到不少在MVP基础上衍生的架子思路,底子是MVP没错,但命名有区别.复杂度变了.架子也用到了 ...

  8. 三言两语聊Python模块–文档测试模块doctest

    doctest是属于测试模块里的一种,对注释文档里的示例进行检测. 给出一个例子: splitter.pydef split(line, types=None, delimiter=None): &q ...

  9. 系统升级日记(1)- 升级到SQL Server 2012

    最近一段时间在公司忙于将各类系统进行升级,其最主要的目标有两个,一个是将TFS2010升级到TFS2013,另外一个是将SharePoint 2010升级到SharePoint 2013.本记录旨在记 ...

  10. [AJAX系列]XMLHttpResponse对象

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...