bzoj3697_FJ2014集训_采药人的路径_solution
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的更多相关文章
- 「FJ2014集训」采药人的路径
啦啦啦 来写一篇题解 洛谷链接: P4930 「FJ2014集训」采药人的路径 统计路径?嗯往点分治上想. 把0和1转化为-1和1,求和完dis为0的路径就是阴阳平衡的路径了. 如果题目没有限制要有中 ...
- P4930「FJ2014集训」采药人的路径
题目:P4930「FJ2014集训」采药人的路径 思路: 这篇不算题解,是让自己复习的,什么都没说清楚. 很久没有写点分治了,以前为了赶课件学的太急,板子都没打对就照着题解写题,导致学得很不扎实. 这 ...
- BZOJ_3697_采药人的路径_点分治
BZOJ_3697_采药人的路径_点分治 Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材. 采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性 ...
- [bzoj3697]采药人的路径_点分治
采药人的路径 bzoj-3697 题目大意:给你一个n个节点的树,每条边分为阴性和阳性,求满足条件的链的个数,使得这条链上阴性的边的条数等于阳性的边的条数,且这条链上存在一个节点,这个节点到一个端点的 ...
- 【BZOJ-3697&3127】采药人的路径&YinandYang 点分治 + 乱搞
3697: 采药人的路径 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 681 Solved: 246[Submit][Status][Discus ...
- 改变Chrome浏览器主程序_缓存_个人信息路径
改变Chrome浏览器缓存_个人信息路径(亲测) actionx2上传于2012-10-26|(7人评价)|3077人阅读|41次下载|文档简介|举报文档 在手机打开 改变 Chrom ...
- 【BZOJ3697】采药人的路径 点分治
[BZOJ3697]采药人的路径 Description 采药人的药田是一个树状结构,每条路径上都种植着同种药材.采药人以自己对药材独到的见解,对每种药材进行了分类.大致分为两类,一种是阴性的,一种是 ...
- bzoj千题计划248:bzoj3697: 采药人的路径
http://www.lydsy.com/JudgeOnline/problem.php?id=3697 点分治 路径0改为路径-1 g[i][0/1] 和 f[i][0/1]分别表示当前子树 和 已 ...
- 【BZOJ】【3697】采药人的路径&【3127】【USACO2013 Open】Yin and Yang
点分治 Orz hzwer 倒是比较好想到点分治……然而在方案统计这里,我犯了两个错误…… 1.我比较傻逼的想的是:通过儿子来更新父亲,也就是统计以x为根的子树中xxxx的路径有多少条……这样转移. ...
随机推荐
- Java中常见的jar包及其主要用途
jar包 用途 axis.jar SOAP引擎包 commons-discovery-0.2.jar 用来发现.查找和实现可插入式接口,提供一些一般类实例化.单件的生命周 ...
- 【转载】Java 9 新特性——模块化
来自 <http://www.jianshu.com/p/053a5ca89bbb#> 前言 年,我们将迎来 Java 语言的 22 岁生日,22岁,对于一个人而言,正是开始大展鸿图的年纪 ...
- Python 求“元组、列表、字典、数组和矩阵”的大小
总结: 首先 import numpy as np A = np.random.randint(1,100,size = (4,5)) >>A>>array([[56, 96, ...
- 【文档】七、Mysql Binlog不同事件类型的事件内容
下面主要讲述了每个类型的事件中的固定和可变部分的数据. Start_log_event_v3/START_EVENT_V3 这个事件出现在v1或v3的binlog文件的开头部分.对于4.0和4.1版本 ...
- Spring整合Hibernate_数据源Datasource_dbcp连接池
1, Spring指定 datasource DataSource接口,在javax.sql包,里边有一个getConnection()方法.提供了标准化的取得连接的方式.只要实现了这个接口.Sun ...
- hibernate_Session接口_load_get
hibernate读取数据库内容,用 1,session.get(Class类型,主键); 立马发出sql语句.从数据库中取出值装到对象里去 2,session.load(Class类型,主键); 从 ...
- cors允许的方法和contype-type
https://fetch.spec.whatwg.org/#cors-safelisted-request-header get head post text/plain multipart/for ...
- springboot-22-自定义starter
先说下springboot的运行原理 springboot最主要的配置 是 @SpringBootApplication 然后这里面 @EnableAutoCOnfiguration 最为重要, 继续 ...
- java的IO流,字节流和字符流
java操作文件都是通过流来处理的,(其实其他很多语言也是这样) 第一:java的IO流,分为:输入流 和 输出流(这真是废话,这是从流向的角度来说的) 第二:java的所有IO流,只分为:字节流 和 ...
- 转载:怎么用eclipse开发C++程序(以后备用,待实现),使用CDT
一:准备工作:需下载以下三个软件包 a).Eclipse 3.1 官方站点: http://www.eclipse.org 工具下载地址:http://www.eclipse.org/download ...
