【BZOJ3697】采药人的路径

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。

题解:可能我以前学的是假的点分治~

注意一点:起点和终点相同,休息点不同的路径,算作相同的路径。

当我们以x为分治中心时,我们遍历x的所有子树,并令f[i][0/1]表示在之前扫过的子树中,到x的路径上的阳-阴=i,不存在(存在)一个休息点的点数,g[i][0/1]表示在当前的子树中,到x的路径上的阳-阴=i,不存在(存在)一个休息站的点数。那么用f和g来更新答案就行了。别忘了算上起点为x的情况。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int maxn=100010;
typedef long long ll;
int n,cnt,root,mx,maxx,tot,d;
ll ans;
int to[maxn<<1],next[maxn<<1],val[maxn<<1],head[maxn],dep[maxn],siz[maxn],vis[maxn],s[maxn];
int f[maxn<<1][2],g[maxn<<1][2];
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void getr(int x,int fa)
{
siz[x]=1;
int mx=0;
for(int i=head[x];i!=-1;i=next[i])
{
if(vis[to[i]]||to[i]==fa) continue;
getr(to[i],x),siz[x]+=siz[to[i]],mx=max(mx,siz[to[i]]);
}
if(max(tot-siz[x],mx)<maxx) root=x,maxx=max(tot-siz[x],mx);
}
void getd(int x,int fa)
{
d=max(d,max(dep[x],-dep[x]));
if(s[dep[x]+maxn]) g[dep[x]+maxn][1]++;
else g[dep[x]+maxn][0]++;
s[dep[x]+maxn]++;
for(int i=head[x];i!=-1;i=next[i])
{
if(vis[to[i]]||to[i]==fa) continue;
dep[to[i]]=dep[x]+val[i],getd(to[i],x);
}
s[dep[x]+maxn]--;
}
void dfs(int x)
{
vis[x]=1;
int i,j,dd=0;
for(i=head[x];i!=-1;i=next[i])
{
if(vis[to[i]]) continue;
dep[to[i]]=val[i],d=0,getd(to[i],x),dd=max(dd,d);
for(j=maxn-d;j<=maxn+d;j++) ans+=(ll)f[2*maxn-j][0]*g[j][1]+f[2*maxn-j][1]*g[j][0]+f[2*maxn-j][1]*g[j][1];
ans+=(ll)f[maxn][0]*g[maxn][0]+g[maxn][1];
for(j=maxn-d;j<=maxn+d;j++) f[j][0]+=g[j][0],f[j][1]+=g[j][1],g[j][0]=g[j][1]=0;
}
for(i=maxn-dd;i<=maxn+dd;i++) f[i][0]=f[i][1]=0;
for(i=head[x];i!=-1;i=next[i])
{
if(vis[to[i]]) continue;
maxx=1<<30,tot=siz[to[i]],getr(to[i],x),dfs(root);
}
}
void add(int a,int b,int c)
{
to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
}
int main()
{
n=rd();
int i,a,b,c;
memset(head,-1,sizeof(head));
for(i=1;i<n;i++) a=rd(),b=rd(),c=rd()*2-1,add(a,b,c),add(b,a,c);
maxx=1<<30,tot=n,getr(1,0),dfs(root);
printf("%lld",ans);
return 0;
}

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

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

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

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

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

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

    Brief 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. thinkphp5 上传服务器后 Access denied

    服务器报 Access denied,要么报 No input files,但是在网上查了查说是将 PHP 的cgi.fix_pathinfo 改成 1 即可,但是改成 1 显然是有解析漏洞的,尝试寻 ...

  2. linux/mac下一键删除下载失败的maven jar包

    echo 正在搜索... find . -name "*lastUpdated" | xargs rm -fr echo 搜索完毕

  3. jqgrid 时间戳转换成日期格式

    原文 :http://blog.csdn.net/caoyuancsdn/article/details/52984524 Java script  接收到的时间参数是时间戳*1000 functio ...

  4. vue2.0项目实战(1)基础入门

    最近公司的H5项目准备重构,部门老大说前端使用vue2.0来开发,所以就准备把整个项目的开发过程记录下来,一方面是为了记录开发过程中遇到的坑,另一方面也加强自己写作的能力. 什么是 Vue? 简要介绍 ...

  5. PHP开发APP接口之返回数据

    首先说明一下客户端APP通信的格式 1.xml:扩展标记语言(1.用来标记数据,定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言,xml格式统一,跨平台和语言,非常适合数据传输和通信,早已 ...

  6. 斯坦福大学公开课机器学习:machine learning system design | data for machine learning(数据量很大时,学习算法表现比较好的原理)

    下图为四种不同算法应用在不同大小数据量时的表现,可以看出,随着数据量的增大,算法的表现趋于接近.即不管多么糟糕的算法,数据量非常大的时候,算法表现也可以很好. 数据量很大时,学习算法表现比较好的原理: ...

  7. request的基本应用

    一.安装 pip install requests (mac前面加sudo) 二.requests的一些参数 method:一般是用的那种请求方法,是get还是post,delete或者delete ...

  8. Tomcat 用 startup.bat 启动时,加载信息之后又关闭服务器(差不多一闪而过)问题

    Tomcat 用 startup.bat 启动时,加载信息之后又关闭服务器(差不多一闪而过)问题 以前是正常的,后来在 server.xml 文件的 <Host> </Host> ...

  9. window下域名解析系统DNS诊断命令nslookup详解

    Ping指令我们很熟悉了,它是一个检查网络状况的命令,在输入的参数是域名的情况下会通过DNS进行查询,但只能查询A记录和CNAME(别名)记录,还会返回域名是否存在,其他的信息都是没有的.如果你需要对 ...

  10. Redis分布式锁----乐观锁的实现,以秒杀系统为例

    本文使用redis来实现乐观锁,并以秒杀系统为实例来讲解整个过程. 乐观锁      大多数是基于数据版本(version)的记录机制实现的.即为数据增加一个版本标识,在基于数据库表的版本解决方案中, ...