每个点维护一颗以深度为下标,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. WebRTC详解-zz

    1.WebRTC目的 WebRTC(Web Real-Time Communication)项目的最终目的主要是让Web开发者能够基于浏览器(Chrome\FireFox\...)轻易快捷开发出丰富的 ...

  2. 脚本病毒分析扫描专题1-VBA代码阅读扫盲、宏病毒分析

    1.Office Macor MS office宏的编程语言是Visual Basic For Applications(VBA). 微软在1994年发行的Excel5.0版本中,即具备了VBA的宏功 ...

  3. swagger学习

    https://segmentfault.com/a/1190000010144742 https://segmentfault.com/a/1190000014775124 https://blog ...

  4. IDL界面程序直接调用envi菜单对应功能

    参考自http://blog.sina.com.cn/s/blog_764b1e9d010115qu.html 参考文章的方法是构建一个button控件,通过单击实现,这种方法比较复杂,不是我们经常能 ...

  5. 含有ref out 参数 的方法反射 Emit 与 普通

    反射中很多朋友应该屡屡被带有ref out参数的方法折腾 当使用正常反射一个方法时候: 代码如下调用一个后期绑定方法MakeByRefType 就行了 MemberInfo test = typeof ...

  6. linux用户权限 -> 系统特殊权限

    set_uid 运行一个命令的时候,相当于这个命令的所有者,而不是执行者的身份. suid的授权方法 suid 权限字符s(S),用户位置上的x位上设置. 授权方法: passwd chmod u+s ...

  7. go语言 documentation

    Documentation文档   The Go programming language is an open source project to make programmers more pro ...

  8. 【前端vue开发】vue开发watch检测的使用

    <span style="color:#006600;"><div id="app"> <input type="tex ...

  9. 虚拟机 ubuntu 16.04

    下载地址:https://www.ubuntu.com/download/desktop 使用虚拟机直接安装

  10. TObject、TPersisent 、TComponent、TControl、TGraphicControl、TWinControl 关系图

    VCL的类图结构               TObject                 |               TPersisent                 |         ...