每个点维护一颗以深度为下标,size-1为值的线段树,保存整颗子树的信息,这样就可以查询了,但是如果为每个节点都建立这么一颗树,显然会MLE,所以考虑在DFS序上建立主席树,然后每个节点原来对应的线段树树就是现在的两个线段树相减所得到的树。

 /**************************************************************
Problem: 3653
User: idy002
Language: C++
Result: Accepted
Time:9276 ms
Memory:114596 kb
****************************************************************/ #include <cstdio>
#define min(a,b) ((a)<(b)?(a):(b))
#define N 300010
#define S 6000000 typedef long long dnt; struct Node {
dnt v;
Node *ls, *rs;
}pool[S], *tail=pool, *null=tail, *root[N]; int n, m;
int head[N], dest[N+N], next[N+N], etot;
int fat[N], dep[N], siz[N], in[N], out[N], vin[N], idc, mdep; void adde( int u, int v ) {
etot++;
next[etot] = head[u];
dest[etot] = v;
head[u] = etot;
}
void dfs( int u ) {
idc++;
in[u] = idc;
vin[idc] = u;
siz[u] = ;
for( int t=head[u]; t; t=next[t] ) {
int v=dest[t];
if( v==fat[u] ) continue;
fat[v] = u;
dep[v] = dep[u]+;
dfs(v);
siz[u] += siz[v];
}
out[u] = idc;
if( dep[u]>mdep ) mdep=dep[u];
}
inline void update( Node *nd ) {
nd->v = nd->ls->v + nd->rs->v;
}
Node *modify( Node *snd, int lf, int rg, int pos, int delta ) {
Node *nnd = ++tail;
if( lf==rg ) {
nnd->v = snd->v + delta;
return nnd;
}
int mid=(lf+rg)>>;
if( pos<=mid ) {
nnd->ls = modify( snd->ls, lf, mid, pos, delta );
nnd->rs = snd->rs;
} else {
nnd->ls = snd->ls;
nnd->rs = modify( snd->rs, mid+, rg, pos, delta );
}
update( nnd );
return nnd;
}
dnt query( Node *nd, int lf, int rg, int L, int R ) {
if( nd==null ) return 0LL;
if( L<=lf && rg<=R )
return nd->v;
int mid=(lf+rg)>>;
dnt rt = 0LL;
if( L<=mid ) rt += query( nd->ls, lf, mid, L, R );
if( R>mid ) rt += query( nd->rs, mid+, rg, L, R );
return rt;
}
void build() {
null->ls = null->rs = null;
null->v = ;
root[] = null;
for( int i=; i<=idc; i++ ) {
root[i] = modify( root[i-], , mdep, dep[vin[i]], siz[vin[i]]- );
}
}
dnt query( int u, int k ) {
dnt ans1 = (dnt) min(k,dep[u]-) * (siz[u]-);
dnt ans2 = 0LL;
if( siz[u]== ) return ans1; ans2 += query( root[out[u]], , mdep, dep[u]+, min( dep[u]+k, mdep ) );
ans2 -= query( root[in[u]], , mdep, dep[u]+, min( dep[u]+k, mdep ) );
return ans1 + ans2;
}
int main() {
scanf( "%d%d", &n, &m );
for( int i=,u,v; i<n; i++ ) {
scanf( "%d%d", &u, &v );
adde( u, v );
adde( v, u );
}
fat[] = ;
dep[] = ;
dfs();
build();
for( int t=,u,k; t<=m; t++ ) {
scanf( "%d%d", &u, &k );
printf( "%lld\n", query(u,k) );
}
}

bzoj 3653的更多相关文章

  1. BZOJ 3653: 谈笑风生(离线, 长链剖分, 后缀和)

    题意 给你一颗有 \(n\) 个点并且以 \(1\) 为根的树.共有 \(q\) 次询问,每次询问两个参数 \(p, k\) .询问有多少对点 \((p, a, b)\) 满足 \(p,a,b\) 为 ...

  2. BZOJ.3653.谈笑风生(长链剖分/线段树合并/树状数组)

    BZOJ 洛谷 \(Description\) 给定一棵树,每次询问给定\(p,k\),求满足\(p,a\)都是\(b\)的祖先,且\(p,a\)距离不超过\(k\)的三元组\(p,a,b\)个数. ...

  3. bzoj 3653 谈笑风生——主席树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3653 原来一直想怎么线段树合并.可是不会把角标挪一位. 查询的其实是子树内一段深度的点的 s ...

  4. bzoj 3653 谈笑风生 —— 主席树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3653 对于一个 (a,b,c),分成 b 是 a 的祖先和 b 在 a 子树里两部分: 第一 ...

  5. BZOJ 3653 谈笑风生

    ORZ blutrex...... 主席树. #include<iostream> #include<cstdio> #include<cstring> #incl ...

  6. BZOJ 3653: 谈笑风生(DFS序+可持久化线段树)

    首先嘛,还是太弱了,想了好久QAQ 然后,这道题么,明显就是求sigma(size[x]) (x是y的儿子且层树小于k) 然后就可以发现:把前n个节点按深度建可持久化线段树,就能用前缀和维护了 其实不 ...

  7. bzoj 3653 [湖南集训]谈笑风生

    题目描述 设 T 为一棵有根树,我们做如下的定义: • 设 a 和 b 为 T 中的两个不同节点.如果 a 是 b 的祖先,那么称"a 比 b 不知道高明到哪里去了". • 设 a ...

  8. 主席树 || 可持久化线段树 || BZOJ 3653: 谈笑风生 || Luogu P3899 [湖南集训]谈笑风生

    题面:P3899 [湖南集训]谈笑风生 题解: 我很喜欢这道题. 因为A是给定的,所以实质是求二元组的个数.我们以A(即给定的P)作为基点寻找答案,那么情况分两类.一种是B为A的父亲,另一种是A为B的 ...

  9. 【刷题】BZOJ 3653 谈笑风生

    Description 设T 为一棵有根树,我们做如下的定义: ? 设a和b为T 中的两个不同节点.如果a是b的祖先,那么称"a比b不知道 高明到哪里去了". ? 设a 和 b 为 ...

随机推荐

  1. 事件,使用.net自带委托EventHandler

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...

  2. C# 浅谈 接口(Interface)的作用

    继承"基类"跟继承"接口"都能实现某些相同的功能,但有些接口能够完成的功能是只用基类无法实现的 1.接口用于描述一组类的公共方法/公共属性. 它不实现任何的方法 ...

  3. clog,cout,cerr 输出机制

    clog:控制输出,使其输出到一个缓冲区,这个缓冲区关联着定义在 <cstdio> 的 stderr. cerr:强制输出刷新,没有缓冲区. cout:控制输出,使其输出到一个缓冲区,这个 ...

  4. python3 切换工作文件夹

    python3 默认的工作文件夹在Python安装路径下.如下为查看工作文件夹路径: >>> import os >>> os.getcwd() 'D:\\Work ...

  5. python configparser配置文件解析器

    一.Configparser 此模块提供实现基本配置语言的ConfigParser类,该语言提供类似于Microsoft Windows INI文件中的结构.我们经常会在一些软件安装目录下看到.ini ...

  6. LeetCode282. Expression Add Operators

    Given a string that contains only digits 0-9 and a target value, return all possibilities to add bin ...

  7. windows 依赖查看

    使用工具Download Process Explorer查看运行程序所依赖的动态库. 中文说明:适用于 Windows 的 Process Explorer 10.21 版

  8. OpenCV处理直方图

    直方图可以用来描述各种不同的事物,如物体的色彩分布.物体边缘梯度模板,以及表示目标位置的当前假设. 简单的说,直方图就是对数据进行统计,将统计值组织到一系列事先定义好的bin中.bin中的数值是从数据 ...

  9. C11多线程

    参考: http://www.oschina.net/translate/cplusplus-11-threading-make-your-multitasking-life http://blog. ...

  10. Observer 观察者

    意图 定义对象间的一种一对多的依赖关系 ,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新. 动机 一致性,松耦合 需要维护相关对象间的一致性.我们不希望为了维持一致性而使各类紧 ...