小道士的矫情之路;
点分治,
对于每个子树,处理其内经过根(重心)的路径,然后递归下一层子树;
如何处理经过根的合法路径
合法有两个要求;
把输入的0改成-1后
1.len=0;
2.存在一个点i使被她分开的两个路径len均为零;
在每次统计中我们可以dfs统计每条从根开始的路径(half_way),
任意两条这样的路径拼成一条可能合法的路径;
check合法?
通过dfs;
统计1,每个half_way的len
还要统计,2,这个half_way上是否有一个点到half_way的终点(根之外的那个)的len=0;
一,两个half_way的len加为0才可能合法;
二,两个half_way中至少一个满足“有一个点到half_way的终点(根之外的那个)的len=0”;
只要满足一&&二,则路径合法;(自己思考why?)
1很好统计;
关键是2;
可以考虑维护一个桶;
如果root到i的路径len=x,且桶x已经有值了,则i的二合法;(自己思考why?)
由于这里细节极多,不好全部言明,故直接看代码:
 long long  get_ans(int root,int w){
int i,j,k,l,kk,ll;
long long ans=;
tot=;if(w)map[zero]=;
dfs_ans(root,w,);j=tot;
sort(hw+,hw+tot+,cmp);
for(i=;i<j;i++){
while(hw[i].d+hw[j].d>&&i<j)
j--;
if(hw[i].d+hw[j].d==){
k=l=;kk=i;ll=j;
if(hw[i].d==){
for(;i<=j;i++){
if(hw[i].can>=)k++;
if(hw[i].can==)l++;
}
ans+=(long long)(k+l)*(k+l-)/;
ans+=(long long)k*(ll-kk+-l-k);
break;
}
while(){
if(hw[i].can)k++;i++;
if(hw[i].d!=hw[i-].d)break;
}
while(){
if(hw[j].can)l++;j--;
if(hw[j].d!=hw[j+].d)break;
}
ans+=(long long)k*(ll-j-l)+l*(i-kk-k)+k*l;i--;
}
}
if(w)map[zero]=;
return ans;
}
void dfs_ans(int now,int sum,int fa){
hw[++tot].d=sum;
hw[tot].can=map[zero+sum];
map[zero+sum]++;
for(int i=first[now];i;i=e[i].next)
if(e[i].to!=fa&&!vis[e[i].to])
dfs_ans(e[i].to,sum+e[i].d,now);
map[zero+sum]--;
}

由于这个操作是单次O(logn)的,于是我的做法比标解多了一个不大log;

(标解O(nlogn),本人O(nlog²n),......大约是这样)

之前桶没清干净,拍了好久没发现;

总代码:

 #include<cstdio>
#include<algorithm>
using namespace std;
const int zero=;
int n,tot;
long long ans;
struct half_way{
int d,can;
}hw[];
int map[],vis[],size[],lsize[];
struct ss{
int to,next,d;
}e[];
int first[],num;
bool cmp(half_way a,half_way b){
return a.d<b.d;
}
void build(int ,int ,int );
void part_dfs(int );
void dfs_size(int ,int );
int dfs_root(int ,int ,int );
long long get_ans(int ,int );
void dfs_ans(int ,int ,int );
int main()
{
int i,j,k,l;
scanf("%d",&n);
for(i=;i<n;i++){
scanf("%d%d%d",&j,&k,&l);
l=l?:-;
build(j,k,l);
build(k,j,l);
}
part_dfs();
printf("%lld",ans);
return ;
}
void build(int f,int t,int wi){
e[++num].next=first[f];
e[num].to=t;e[num].d=wi;
first[f]=num;
}
void part_dfs(int now){
int i,root;
dfs_size(now,);
root=dfs_root(now,,now);
ans+=get_ans(root,);
vis[root]=;
for(i=first[root];i;i=e[i].next)
if(!vis[e[i].to]){
ans-=get_ans(e[i].to,e[i].d);
part_dfs(e[i].to);
}
}
void dfs_size(int now,int fa){
size[now]=;
for(int i=first[now];i;i=e[i].next)
if(!vis[e[i].to]&&e[i].to!=fa){
dfs_size(e[i].to,now);
size[now]+=size[e[i].to];
}
}
int dfs_root(int now,int fa,int r){
int i,root=-,wroot;
lsize[now]=size[r]-size[now];
for(i=first[now];i;i=e[i].next)
if(!vis[e[i].to]&&e[i].to!=fa){
if(size[e[i].to]>lsize[now])
lsize[now]=size[e[i].to];
wroot=dfs_root(e[i].to,now,r);
if(lsize[wroot]<lsize[root]||root==-)
root=wroot;
}
if(lsize[now]<lsize[root]||root==-)
root=now;
return root;
}
long long get_ans(int root,int w){
int i,j,k,l,kk,ll;
long long ans=;
tot=;if(w)map[zero]=;
dfs_ans(root,w,);j=tot;
sort(hw+,hw+tot+,cmp);
for(i=;i<j;i++){
while(hw[i].d+hw[j].d>&&i<j)
j--;
if(hw[i].d+hw[j].d==){
k=l=;kk=i;ll=j;
if(hw[i].d==){
for(;i<=j;i++){
if(hw[i].can>=)k++;
if(hw[i].can==)l++;
}
ans+=(long long)(k+l)*(k+l-)/;
ans+=(long long)k*(ll-kk+-l-k);
break;
}
while(){
if(hw[i].can)k++;i++;
if(hw[i].d!=hw[i-].d)break;
}
while(){
if(hw[j].can)l++;j--;
if(hw[j].d!=hw[j+].d)break;
}
ans+=(long long)k*(ll-j-l)+l*(i-kk-k)+k*l;i--;
}
}
if(w)map[zero]=;
return ans;
}
void dfs_ans(int now,int sum,int fa){
hw[++tot].d=sum;
hw[tot].can=map[zero+sum];
map[zero+sum]++;
for(int i=first[now];i;i=e[i].next)
if(e[i].to!=fa&&!vis[e[i].to])
dfs_ans(e[i].to,sum+e[i].d,now);
map[zero+sum]--;
}

从时间复杂度和代码量上都不如标解,唉,也难怪;

bzoj3697_FJ2014集训_采药人的路径_solution的更多相关文章

  1. 「FJ2014集训」采药人的路径

    啦啦啦 来写一篇题解 洛谷链接: P4930 「FJ2014集训」采药人的路径 统计路径?嗯往点分治上想. 把0和1转化为-1和1,求和完dis为0的路径就是阴阳平衡的路径了. 如果题目没有限制要有中 ...

  2. P4930「FJ2014集训」采药人的路径

    题目:P4930「FJ2014集训」采药人的路径 思路: 这篇不算题解,是让自己复习的,什么都没说清楚. 很久没有写点分治了,以前为了赶课件学的太急,板子都没打对就照着题解写题,导致学得很不扎实. 这 ...

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

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

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

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

  5. 【BZOJ-3697&3127】采药人的路径&YinandYang 点分治 + 乱搞

    3697: 采药人的路径 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 681  Solved: 246[Submit][Status][Discus ...

  6. 改变Chrome浏览器主程序_缓存_个人信息路径

      改变Chrome浏览器缓存_个人信息路径(亲测) actionx2上传于2012-10-26|(7人评价)|3077人阅读|41次下载|文档简介|举报文档    在手机打开   改变 Chrom ...

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

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

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

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

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

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

随机推荐

  1. js的语言的理解

    1.所谓字面量,就是语言语法 2.在js编译器读到语法时候,执行时候创建对象:在赋值的时候创建一个对象,或者是一个匿名对象. 3.函数定义本身是一个对象:执行时候不产生实例对象:这跟python类不一 ...

  2. angular4套用primeng样式

    首先安装primeng cnpm install primeng --save 这样会在项目目录中增加node_modules\primeng目录 package.json文件增加了以下一行 &quo ...

  3. springcloud(六)-Ribbon配置自定义算法

    前言 很多场景下,可能根据需要自定义Ribbon的配置,例如修改Ribbon的负载均衡规则等.Spring Cloud Edgware允许使用java代码或属性自定义Ribbon 的配置,两种方式等价 ...

  4. 【GIS新探索】GeoHash原理和编解码实现

    1.什么是GeoHash geohash基本原理是将地球理解为一个二维平面,将平面递归分解成更小的子块,每个子块在一定经纬度范围内拥有相同的编码.不好理解,没关系,我来找个图. 就像上面这张图,一个坐 ...

  5. How to install Jenkins on CentOS 7

    How to install Jenkins on CentOS 7 on March 3, 2018 by AmirLeave a comment Introduction Jenkins is a ...

  6. (转)CentOS 7 安装 Python3、pip3

    原文:https://ehlxr.me/2017/01/07/CentOS-7-%E5%AE%89%E8%A3%85-Python3%E3%80%81pip3/ CentOS 7 默认安装了 Pyth ...

  7. WPF中用后台C#代码为TabItem设置Background属性

    TabItem tabItem = sender as TabItem; tabItem.Background = new ImageBrush(new BitmapImage(new Uri(@&q ...

  8. leetcode1:线性表

    //定义二维数组int **array = new int*[row_num]; ;i<row_num;i++) { array[i] = new int[col_num]; } vector& ...

  9. Leetcode 337. House Robber III

    337. House Robber III Total Accepted: 18475 Total Submissions: 47725 Difficulty: Medium The thief ha ...

  10. http请求数据封装

    package com.wdm.utils; import java.io.ByteArrayOutputStream; import java.io.IOException; import java ...