转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove

题目:给出一棵树,问有多少条路径权值和不大于w,长度不大于l。

http://codeforces.com/contest/293/problem/E

有男人八题很相似,但是多了一个限制。

同样 还是点分治,考虑二元组(到根的路径权值和,到根的路径长度)。

按第一维度排序之后,可以用two points查询权值小不大于w的,然后 用树状数组维护路径长度。

也就是第一个条件用two points,第二个条件用树状数组维护。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#define lson step << 1
#define rson step << 1 | 1
#define pb(a) push_back(a)
#define mp(a,b) make_pair(a , b)
#define lowbit(x) (x & (-x))
#pragma comment(linker, "/STACK:1024000000,1024000000")
using namespace std;
typedef long long LL;
const int N = 100005;
struct Edge {
int v , w , next;
}e[N << 1];
int n , l , w , tot , start[N];
int del[N] = {0} , size[N];
LL ans = 0LL;
void _add (int u , int v , int w) {
e[tot].v = v ; e[tot].next = start[u];
e[tot].w = w;
start[u] = tot ++;
}
void add (int u , int v , int w) {
_add (u , v , w);
_add (v , u , w);
}
void calsize (int u , int pre) {
size[u] = 1;
for (int i = start[u] ; i != -1 ; i = e[i].next) {
int v = e[i].v;
if (v == pre || del[v]) continue;
calsize (v , u);
size[u] += size[v];
}
}
int totalsize , maxsize , rootidx;
void dfs (int u , int pre) {
int mx = totalsize - size[u];
for (int i = start[u] ; i != -1 ; i = e[i].next) {
int v = e[i].v;
if (v == pre || del[v]) continue;
mx = max (mx , size[v]);
dfs (v , u);
}
if (mx < maxsize) maxsize = mx , rootidx = u;
}
int search (int r) {
calsize (r , -1);
totalsize = size[r];
maxsize = 1 << 30;
dfs (r , -1);
return rootidx;
}
vector<pair<int,int> > sub[N] , all;
int idx , dist[N] , cnt[N];
void gao (int u , int pre) {
all.pb(mp(dist[u] , cnt[u]));
sub[idx].pb(mp(dist[u] , cnt[u]));
for (int i = start[u] ; i != -1 ; i = e[i].next) {
int v = e[i].v , w = e[i].w;
if (v == pre || del[v]) continue;
dist[v] = dist[u] + w;
cnt[v] = cnt[u] + 1;
gao (v , u);
}
}
int s[N] , up;
void add (int x , int val) {
for (int i = x ; i <= up ; i += lowbit (i)) {
s[i] += val;
}
}
int ask (int x) {
int ret = 0;
for (int i = x ; i > 0 ; i -= lowbit (i)) {
ret += s[i];
}
return ret;
}
LL fuck (vector<pair<int , int> > &v) {
LL ret = 0;
up = 0;
for (int i = 0 ; i < v.size() ; i ++)
up = max (up , v[i].second);
for (int i = 1 ; i <= up ; i ++)
s[i] = 0;
for (int i = 0 ; i < v.size() ; i ++)
add (v[i].second , 1);
for (int i = 0 , j = v.size() - 1 ; i < v.size() ; i ++) {
while (j >= i && v[i].first + v[j].first > w) {
add (v[j].second , -1);
j --;
}
if (j < i) break;
ret += ask (min(up , (l - v[i].second)));
add (v[i].second , -1);
}
return ret;
}
void solve (int root) {
root = search (root);
del[root] = 1;
if (totalsize == 1) return ;
idx = 0 ;all.clear();
for (int i = start[root] ; i != -1 ; i = e[i].next) {
int v = e[i].v , w = e[i].w;
if (del[v]) continue;
sub[idx].clear();
dist[v] = w ; cnt[v] = 1;
gao (v , -1);
sort (sub[idx].begin() , sub[idx].end());
idx ++;
}
sort (all.begin() , all.end());
ans += fuck (all);
for (int i = 0 ; i < idx ; i ++) {
for (int j = 0 ; j < sub[i].size() ; j ++) {
if (sub[i][j].first <= w && sub[i][j].second <= l) {
ans ++;
}
}
ans -= fuck (sub[i]);
}
for (int i = start[root] ; i != -1 ; i = e[i].next) {
int v = e[i].v;
if (del[v]) continue;
solve (v);
}
}
int main () {
// freopen ("input.txt" , "r" , stdin);
// freopen ("output.txt" , "w" , stdout);
tot = 0;memset (start , -1 , sizeof(start));
scanf ("%d %d %d" , &n , &l , &w);
for (int i = 1 ; i < n ; i ++) {
int p , d;
scanf ("%d %d" , &p , &d);
add (i + 1 , p , d);
}
solve (1);
printf ("%I64d\n" , ans);
return 0;
}

CF 293 E Close Vertices (树的分治+树状数组)的更多相关文章

  1. 【bzoj3648】环套树+点分治+树状数组

    tree 1s 128M  by hzw czy神犇种了一棵树,他想知道地球的质量 给定一棵n个点的树,求树上经过点的个数≥K的路径数量ans 对于部分数据,树上某两点间会多出最多一条无向边 输入数据 ...

  2. hdu_4918_Query on the subtree(树的分治+树状数组)

    题目链接:hdu_4918_Query on the subtree 题意: 给出一颗n个点的树,每个点有一个权值,有两种操作,一种是将某个点的权值修改为v,另一种是查询距离点u不超过d的点的权值和. ...

  3. [bzoj3155]Preprefix sum(树状数组)

    3155: Preprefix sum Time Limit: 1 Sec  Memory Limit: 512 MBSubmit: 1183  Solved: 546[Submit][Status] ...

  4. Codeforces 980E The Number Games - 贪心 - 树状数组

    题目传送门 传送点I 传送点II 传送点III 题目大意 给定一颗有$n$个点的树,$i$号点的权值是$2^{i}$要求删去$k$个点,使得剩下的点仍然连通,并且总权值和最大,问删去的所有点的编号. ...

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

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

  6. HDU4918 Query on the subtree 点分治+树状数组

    bobo has a tree, whose vertices are conveniently labeled by 1,2,…,n. At the very begining, the i-th ...

  7. bzoj3648: 寝室管理(环套树+点分治)

    好题..写了两个半小时hh,省选的时候要一个半小时内调出这种题目还真是难= = 题目大意是给一棵树或环套树,求点距大于等于K的点对数 这里的树状数组做了一点变换.不是向上更新和向下求和,而是反过来,所 ...

  8. 【BZOJ-3648】寝室管理 环套树 + 树状数组 + 点分治

    3648: 寝室管理 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 239  Solved: 106[Submit][Status][Discuss] ...

  9. CF #365 (Div. 2) D - Mishka and Interesting sum 离线树状数组

    题目链接:CF #365 (Div. 2) D - Mishka and Interesting sum 题意:给出n个数和m个询问,(1 ≤ n, m ≤ 1 000 000) ,问在每个区间里所有 ...

随机推荐

  1. 指定端口号,多线程扫描局域网内IP地址

    小白第一次发博客,请各路大神不要喷,有错的地方还请不吝啬指教,谢谢....... 因为注释基本上已经说清楚啦,在这里就不多说什么啦,知识不够怕误人子弟 # -*- coding:utf-8 -*-im ...

  2. windows程序设计读书笔记4——字符显示3

    在之前的一章里我们使用InvalidateRect函数,生成窗口重绘消息进行重绘,但是并没有在处理滚动条消息时直接绘制,这样的代码效率并不高. 这里作者使用了UpdateWindow函数,直接进行窗口 ...

  3. rabbitmq问题之HTTP access denied: user 'guest' - User can only log in via localhost

    问题: 昨天安装rabbitmq(3.3.4版本)服务,并启用rabbitmq_management插件去管理rabbitmq服务,但是在访问管理界面使用guest用户登录时出现login faile ...

  4. poj1477---搭积木

    #include<stdio.h> #include<stdlib.h> int main() { int n,i; int bricks[55],set=0; while(s ...

  5. mysql SELECT FOUND_ROWS()与COUNT(*)用法区别

    在mysql中 FOUND_ROWS()与COUNT(*)都可以统计记录,如果都一样为什么会有两个这样的函数呢,下面我来介绍SELECT FOUND_ROWS()与COUNT(*)用法区别   SEL ...

  6. 滴滴专车司机苹果手机ios客户端可以下载了

    申请过滴滴专车司机的朋友都知道,滴滴专车就是滴滴打车的司机端,但是只有安卓的,一直没有苹果IOS的版本,很多申请通过审核的车主恼于没有IOS版本而暂无法使用滴滴专车司机客户端,也就意味着不能上线接单. ...

  7. PHP自定义函数与字符串处理

    自定义函数:    1.默认值的函数:    function Main($a=5,$b=6)    {        echo $a*$b;    } 2.可变参数的函数:    function ...

  8. 网易云课堂_程序设计入门-C语言_第六章:数组_2鞍点

    2 鞍点(5分) 题目内容: 给定一个n*n矩阵A.矩阵A的鞍点是一个位置(i,j),在该位置上的元素是第i行上的最大数,第j列上的最小数.一个矩阵A也可能没有鞍点. 你的任务是找出A的鞍点. 输入格 ...

  9. xCode6制作动态及静态Framework(转)

    原文:http://years.im/Home/Article/detail/id/52.html 相关推荐:http://www.cocoachina.com/ios/20150127/11022. ...

  10. Eclipse快捷键大全(一)

    Eclipse快捷键大全(一) 常用(系统默认): 1.Format (自动排版) : Ctrl+Shift+F 2.Organize Imports (自动导入) : Ctrl+Shift+O 3. ...