cf293E Close Vertices(树分治+BIT)
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.
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.
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.
4 4 6
1 3
1 4
1 3
4
6 2 17
1 3
2 5
2 13
1 6
5 9
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)的更多相关文章
- CF293E Close Vertices 点分治+树状数组
开始zz写了一个主席树,后来发现写个树状数组就行~ #include <cstdio> #include <vector> #include <algorithm> ...
- HDU 4812 D Tree 树分治+逆元处理
D Tree Problem Description There is a skyscraping tree standing on the playground of Nanjing Unive ...
- POJ 1741 Tree 树分治
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...
- POJ 1741.Tree 树分治 树形dp 树上点对
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 24258 Accepted: 8062 Description ...
- poj 1744 tree 树分治
Tree Time Limit: 1000MS Memory Limit: 30000K Description Give a tree with n vertices,each ed ...
- poj 1741 楼教主男人八题之中的一个:树分治
http://poj.org/problem? id=1741 Description Give a tree with n vertices,each edge has a length(posit ...
- hdu-5977 Garden of Eden(树分治)
题目链接: Garden of Eden Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/ ...
- 【BZOJ-1468】Tree 树分治
1468: Tree Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1025 Solved: 534[Submit][Status][Discuss] ...
- BZOJ 2152: 聪聪可可 树分治
2152: 聪聪可可 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一 ...
随机推荐
- Java学习笔记(基本数据类型和变量命名规则)
java基本数据类型 变量 1.变量就是可变的量. 2.常量就是不可变的量. 3.字面量:Java的变量和常量中存放的具体的数据成为字面量. 变量 命名规则: (1)首字母是英文字母.$或下划线,由字 ...
- WPF 得一些问题汇总
1.CallMethodAction <TextBox Height="30" Name="txtUserName" Width="160&qu ...
- CUDA获取显卡数据
一个简单的获取Nvidia显卡信息的程序 #include<iostream> int main() { cudaDeviceProp prop; int count; cudaGetDe ...
- ORA-01033 ORA-01109 ORA-01034 ORA-12514 ORA-24324 ORA-01041 ORA-01157 ORA-01110
客户数据库挂掉了 在plsql客户端使用普通账号登录时提示如下错误 因为好久没弄数据库了,慌了一小下. 接下来搜索过往的知识,回忆.在cli下输入了以下命令 sqlplus system/system ...
- SAR ADC简介
SAR型 (逐次逼近型) 摘要:逐次逼近寄存器型(SAR)模数转换器(ADC)占据着大部分的中等至高分辨率ADC市场.SAR ADC的采样速率最高可达5Msps,分辨率为8位至18位.SAR架构允许高 ...
- iOS开发之iOS程序偏好设置(Settings Bundle)的使用
目录[-] 1.添加设置项 2.设置的控件 3.编辑设置项的文件 4.在程序中获取Settings 和写入Settings 添加UI 5.实现读取设置和保存代码 在Android手机上, 在某个程序里 ...
- QT窗口渐现效果,窗口震动效果,鼠标移动窗口
//窗口渐现效果void MainWindow::closeWindowAnimation() //关闭窗口效果 { QPropertyAnimation *animation = new QProp ...
- Ajax、Comet、HTML 5 Web Sockets技术比较分析
最近因为考虑研究B/S结构网站即时消息处理 参考了 JAVA怎么样实现即时消息提醒http://bbs.csdn.net/topics/330015611http://www.ibm.com/deve ...
- servlet 默认是线程安全的吗?
由于Servlet默认是以多线程模式执行的,所以,在编写代码时需要非常细致地考虑多线程的安全问题.然而,很多人编写Servlet程序时并没 有注意到多线程安全的问题,这往往造成编写的程序在少量用户访问 ...
- uva 1396 - Most Distant Point from the Sea
半平面的交,二分的方法: #include<cstdio> #include<algorithm> #include<cmath> #define eps 1e-6 ...