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. Javascript备忘复习笔记2

    一.函数与形参 1.函数 function abs(x) { if (x >= 0) { return x; } else { return -x; } } alert(abs(-10)); 2 ...

  2. sublime和python--path

    配置Sublime Text 2 的Python运行环境 (2013-09-11 11:36:17) 转载▼ 标签: python 分类: 科技相关     Sublime Text 2作为一款轻量级 ...

  3. php常用函数(不定时更新)

    一,数据操作类 1,天花板函数(ceil)和地板函数(floor) 这两个函数是对数据进行向上取整和向下取整的操作的,比如说 echo ceil("3.01"); //这里输出的是 ...

  4. 史上最全的CSS hack方式一览

    做前端多年,虽然不是经常需要hack,但是我们经常会遇到各浏览器表现不一致的情况.基于此,某些情况我们会极不情愿的使用这个不太友好的方式来达到大家要求的页面表现.我个人是不太推荐使用hack的,要知道 ...

  5. 043医疗项目-模块四:采购单模块—采购单明细查询(Dao,Service,Action三层)

    前一篇文章我们做的是在医院的角度上添加在采购单里面添加药品.这一篇文章是查看我们添加的采购单信息. 我们先看一下要实现的效果:当: 按下确认添加时,会在这里 显示出刚才添加的数据. 好,我们就来做这个 ...

  6. codevs 2606 约数和问题

    题目描述 Description Smart最近沉迷于对约数的研究中. 对于一个数X,函数f(X)表示X所有约数的和.例如:f(6)=1+2+3+6=12.对于一个X,Smart可以很快的算出f(X) ...

  7. Alwayson--SYS.dm_hadr_instance_node_map 返回0行

    下面是MSDN关于SYS.dm_hadr_instance_node_map 的解释,我就不在翻译了 For every instance of SQL Server that hosts an av ...

  8. Android -- ActivityLifeCycleCallbacks

    ActivityLifeCycleCallbacks Application通过此接口提供了一套回调方法,用于让开发者对Activity的生命周期事件进行集中处理. 为什么用ActivityLifec ...

  9. ASP.NET XmlSerializer权限问题

    今天碰到一个奇怪问题.因为在2台服务器上做文件共享,使服务器A能访问服务器B的共享目录.在IIS上使用虚拟目录实现的话,需要给应用程序池指定一个统一的账号.在调试的时候能够使用,但是一部署到服务器上, ...

  10. VS2013无法链接到TFS(Visual studio online),错误TF31001,TF31002

    TF31002: Unable to connect to VisualStudio Online with VS 2013 but I can using web access - Windows ...