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. Razor 模板自己渲染出结果 string

    using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNet ...

  2. Html5的一些引擎使用感触

    记得在2011年的时候,51CTO曾经采访我对H5的看法,因为当时Html5小组和雷友的关系,感觉是一片大火的形式,当时我的看法是:第一盈利模式不清晰,第二硬件跟不上,第三技术不成熟. 第一和第二点很 ...

  3. NET Core项目定义Item Template

    NET Core项目定义Item Template 作为这个星球上最强大的IDE,Visual Studio不仅仅提供了很多原生的特性,更重要的是它是一个可定制的IDE,比如自定义Project Te ...

  4. 数据库 Linux下的MySQL数据库管理

    数据库就是数据的集合. 关系数据库是一种特殊的数据库,他将数据组织城标,并表示为表之间的关系. 数据库系统往往是大型项目的核心数据内容,如银行的用户账户信息,腾讯QQ的用户账户信息.股市的各种交易信息 ...

  5. VS改大小写的快捷键

    改成小写:Ctrl+U 改成大写:Ctrl+Shift+U 记得要选中要修改的一段英文.

  6. 博客搬家。新博客地址 http://fangjian0423.github.io/

    以后新的博客会发到 http://fangjian0423.github.io/ 里. 这里基本上不会再更新博客了.

  7. 在线音乐网站【04】Part two 功能实现

       上一篇博客里面已近总结了三个功能的具体实现,今天把剩余功能的具体实现补充总结,如果你想对整个小项目有清楚的了解,建议去看下前几篇博客. 1.在线音乐网站(1)需求和功能结构 2.在线音乐网站(2 ...

  8. 写个屏蔽百度搜索广告的Chrome插件

    工作生活都用百度比较多,毕竟它是目前为止感觉最好的国内PC搜索引擎.我纵使已经差不多炼成了一眼过滤广告的眼力,但始终觉得碍眼,感觉还是写个插件把它屏蔽了吧.这个插件开发的门槛其实非常低,只是一开始做不 ...

  9. html文本标准模式,首行空两格,两端对齐,行高

    font-size: 13px; line-height: 1.6; text-align: justify; text-indent: 2em;

  10. 浅析手机抓包方法实践(zt)

    原文:http://drops.wooyun.org/tips/12467 0x00 摘要 在移动逆向分析以及 App 开发的时候,总会需要对其网络行为进行监控测试,本文总结一些抓包思路,并对其使用方 ...