E. Close Vertices

You've got a weighted tree, consisting of n vertices. Each edge has a non-negative weight. The length of the path between any two vertices of the tree is the number of edges in the path. The weight of the path is the total weight of all edges it contains.

Two vertices are close if there exists a path of length at most l between them and a path of weight at most w between them. Count the number of pairs of vertices v, u (v < u), such that vertices v and u are close.

Input

The first line contains three integers n, l and w (1 ≤ n ≤ 105, 1 ≤ l ≤ n, 0 ≤ w ≤ 109). The next n - 1 lines contain the descriptions of the tree edges. The i-th line contains two integers pi, wi (1 ≤ pi < (i + 1), 0 ≤ wi ≤ 104), that mean that the i-th edge connects vertex (i + 1) and pi and has weight wi.

Consider the tree vertices indexed from 1 to n in some way.

Output

Print a single integer — the number of close pairs.

Please, do not use the %lld specifier to read or write 64-bit integers in С++. It is preferred to use the cin, cout streams or the %I64d specifier.

Sample test(s)
Input
4 4 6
1 3
1 4
1 3
Output
4
Input
6 2 17
1 3
2 5
2 13
1 6
5 9
Output
9

【思路】

树分治。大体思路和这道题相似。

不同的是有两个需要满足的条件,只需要把dis排序,扫描的同时用BIT维护dep的区间信息并统计答案即可。

【代码】

 #include<map>
#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
#include<algorithm>
#define FOR(a,b,c) for(int a=(b);a<=(c);a++)
using namespace std; typedef long long LL;
const int N = 1e5+;
const int INF = 1e9+;
struct Edge {
int v,w;
Edge(int v=,int w=) :v(v),w(w){}
};
int n,W,L; LL ans;
int root,size,vis[N],siz[N],f[N],dis[N],dep[N],l1,l2;
pair<int,int> list[N];
vector<int> rec;
vector<Edge> g[N];
//BIT
int C[N];
void add(int x,int v) {
while(x<=n) C[x]+=v,x+=x&(-x);
}
int query(int x) {
int ans=;
while(x>) ans+=C[x],x-=x&(-x);
return ans;
}
//fenzhi
void getroot(int u,int fa) {
siz[u]=; f[u]=;
for(int i=;i<g[u].size();i++) {
int v=g[u][i].v;
if(v!=fa && !vis[v]) {
getroot(v,u);
siz[u]+=siz[v];
f[u]=max(f[u],siz[v]);
}
}
f[u]=max(f[u],size-siz[u]);
if(f[u]<f[root]) root=u;
}
void getdis(int u,int fa) {
list[++l1]=make_pair(dis[u],dep[u]);
for(int i=;i<g[u].size();i++) {
int v=g[u][i].v;
if(v!=fa && !vis[v]) {
dep[v]=dep[u]+;
dis[v]=dis[u]+g[u][i].w;
getdis(v,u);
}
}
}
LL getans(int l,int r) {
sort(list+l,list+r+);
LL res=; int j=l;
for(int i=r;i>=l;i--) {
while(j<=r && list[i].first+list[j].first<=W) {
add(list[j].second,);
rec.push_back(list[j].second);
j++;
}
if(list[i].first*<=W && list[i].second*<=L) res--;
res+=(LL)query(L-list[i].second);
}
return res/;
}
void clear() {
for(int i=;i<rec.size();i++) add(rec[i],-);
rec.clear();
}
void solve(int u) {
vis[u]=; l1=l2=;
LL S1=,S2=;
for(int i=(int)g[u].size()-;i>=;i--) {
int v=g[u][i].v;
if(!vis[v]) {
l2=l1+;
dep[v]=; dis[v]=g[u][i].w;
getdis(v,u);
clear();
S1+=getans(l2,l1);
}
}
FOR(i,,l1) //AT:根为终点
if(list[i].first<=W && list[i].second<=L) S2++;
clear(); //AT:clear
S2+=getans(,l1);
ans=ans+S2-S1;
for(int i=(int)g[u].size()-;i>=;i--) {
int v=g[u][i].v;
if(!vis[v]) {
size=siz[v]; root=;
getroot(v,-); solve(root);
}
}
} void read(int& x) {
char c=getchar(); int f=; x=;
while(!isdigit(c)) {if(c=='-')f=-;c=getchar();}
while(isdigit(c)) x=x*+c-'',c=getchar();
x*=f;
}
int main() {
//freopen("in.in","r",stdin);
//freopen("out.out","w",stdout);
read(n),read(L),read(W);
int u,v,w;
FOR(i,,n) {
read(u),read(v),read(w);
g[u].push_back(Edge(v,w));
g[v].push_back(Edge(u,w));
}
root=,f[]=INF,size=n;
getroot(,-); solve(root);
cout<<ans;
return ;
}

cf293E Close Vertices(树分治+BIT)的更多相关文章

  1. CF293E Close Vertices 点分治+树状数组

    开始zz写了一个主席树,后来发现写个树状数组就行~ #include <cstdio> #include <vector> #include <algorithm> ...

  2. HDU 4812 D Tree 树分治+逆元处理

    D Tree Problem Description   There is a skyscraping tree standing on the playground of Nanjing Unive ...

  3. POJ 1741 Tree 树分治

    Tree     Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...

  4. POJ 1741.Tree 树分治 树形dp 树上点对

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 24258   Accepted: 8062 Description ...

  5. poj 1744 tree 树分治

    Tree Time Limit: 1000MS   Memory Limit: 30000K       Description Give a tree with n vertices,each ed ...

  6. poj 1741 楼教主男人八题之中的一个:树分治

    http://poj.org/problem? id=1741 Description Give a tree with n vertices,each edge has a length(posit ...

  7. hdu-5977 Garden of Eden(树分治)

    题目链接: Garden of Eden Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/ ...

  8. 【BZOJ-1468】Tree 树分治

    1468: Tree Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1025  Solved: 534[Submit][Status][Discuss] ...

  9. BZOJ 2152: 聪聪可可 树分治

    2152: 聪聪可可 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一 ...

随机推荐

  1. Codevs 1958 刺激

    1958 刺激 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description saffah的一个朋友S酷爱滑雪,并且追求刺激(exitement, ...

  2. java.util.Dictionary源码分析

    Dictionary是一个抽象类,Hashtable是它的一个子类. 类的声明:/** The <code>Dictionary</code> class is the abs ...

  3. DataReader 和 DataSet 的区别

    摘自:http://www.cnblogs.com/zhjjNo1/archive/2009/08/26/1554420.html 第一种解释 DataReader和DataSet最大的区别在于,Da ...

  4. 用C#实现MD5算法

     /// <summary>     /// 一个实现MD5散列字符串的类     /// </summary>     public sealed class MD5Hash ...

  5. 【转】C#窗体飞入飞出的动画效果(Api)

    [System.Runtime.InteropServices.DllImport("user32")] private static extern bool AnimateWin ...

  6. [转] 使用maven运行java main的三种方式

    原文地址: http://blog.csdn.net/qbg19881206/article/details/19850857?utm_source=tuicool&utm_medium=re ...

  7. 在ecshop商品详情页显示供货商

    好久没写文章了,隐约记得前几天有人问到这个问题:[如何在ecshop商品详情页面显示该商品的供货商?] 今天有时间整理下,分享给大家. 注:以下修改适用于ecshop2.7.2,其他版本未做测试. 1 ...

  8. 操作系统和Python的发展历程

    一:操作系统的发展历史: 操作系统:什么是操作系统?我们首先想到的是电脑,,也就是所谓的Windows8,Windows7,或者XP系统和Windows10,当然也包括我们手机的安卓系统或者IPhon ...

  9. 【原创】Mvc学习笔记(1)

    1.新建MVC4项目 在MVC4中有App_Data文件夹,这个文件夹里可以放一些重要的数据,比如说数据库的mdf文件等等,这个文件夹非常安全,因为这个文件夹不允许被别人下载,不允许被浏览器访问. A ...

  10. 浅谈JavaScript的push()函数

    push() 方法可向数组的末尾添加一个或多个元素,并返回新的长度.返回值是把指定的值添加到数组后的新长度. 语法:arrayObject.push(newelement1,newelement2,. ...