Description

Atm有一段时间在虐qtree的题目,于是,他满脑子都是tree,tree,tree……
于是,一天晚上他梦到自己被关在了一个有根树中,每条路径都有边权,一个神秘的声音告诉他,每个点到其他的点有一个距离(什么是距离不用说吧),他需要对于每个点回答:从这个点出发的第k小距离是多少;
如果atm不能回答出来,那么明天4019的闹钟将不会响,4019全寝可能就迟到了,所以atm希望你帮帮他。

Input

第一行,两个正整数n,k,表示树的点数,询问的是第几小距离;
第二~n行,每行三个正整数x,y,w,表示x和y之间有一条边,x为父亲,边权为w;

Output

n行, 每行一个数,第i行输出从i开始第k小距离

Sample Input

5 2
1 5 2
1 2 4
2 3 6
2 4 5

Sample Output

4
5
10
9
6

HINT

100% n<=15000, 边权在1~10之间,为了方便,保证1为根;
动态树分治套Treap。。。
#include<cstdio>
#include<cctype>
#include<queue>
#include<cstring>
#include<algorithm>
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using namespace std;
inline int read() {
int x=,f=;char c=getchar();
for(;!isdigit(c);c=getchar()) if(c=='-') f=-;
for(;isdigit(c);c=getchar()) x=x*+c-'';
return x*f;
}
const int maxn=;
struct Node {
Node* ch[];
int r,s,v;
void maintain() {s=ch[]->s+ch[]->s+;}
}nodes[maxn*],*null=&nodes[];
int ToT;queue<Node*> Q;
Node* newnode(int v) {
Node* o;
if(Q.empty()) o=&nodes[++ToT];
else o=Q.front(),Q.pop();
o->v=v;o->s=;o->ch[]=o->ch[]=null;o->r=rand();
return o;
}
void del(Node* &o) {Q.push(o);o=null;}
void rotate(Node* &o,int d) {
Node* k=o->ch[d^];o->ch[d^]=k->ch[d];k->ch[d]=o;
o->maintain();k->maintain();o=k;
}
void insert(Node* &o,int v) {
if(o==null) o=newnode(v);
else {
int d=v>o->v;insert(o->ch[d],v);
if(o->ch[d]->r>o->r) rotate(o,d^);
else o->maintain();
}
}
int query(Node* &o,int v) {
if(o==null) return ;
if(v>o->v) return query(o->ch[],v)+o->ch[]->s+;
return query(o->ch[],v);
}
int n,m,first[maxn],next[maxn<<],to[maxn<<],dis[maxn<<],e;
void AddEdge(int w,int v,int u) {
dis[++e]=w;to[e]=v;next[e]=first[u];first[u]=e;
dis[++e]=w;to[e]=u;next[e]=first[v];first[v]=e;
}
int dep[maxn],mn[maxn<<][],Log[maxn<<],cnt,pos[maxn];
void dfs(int x,int fa) {
mn[++cnt][]=dep[x];pos[x]=cnt;
ren if(to[i]!=fa) {
dep[to[i]]=dep[x]+dis[i];
dfs(to[i],x);
mn[++cnt][]=dep[x];
}
}
void pre() {
Log[]=-;
rep(i,,cnt) Log[i]=Log[i>>]+;
for(int j=;(<<j)<=cnt;j++)
for(int i=;i+(<<j)-<=cnt;i++)
mn[i][j]=min(mn[i][j-],mn[i+(<<j-)][j-]);
}
int dist(int x,int y) {
int ans=dep[x]+dep[y];
x=pos[x];y=pos[y];if(x>y) swap(x,y);
int k=Log[y-x+];
return ans-*min(mn[x][k],mn[y-(<<k)+][k]);
}
int f[maxn],s[maxn],vis[maxn],size,rt;
void getroot(int x,int fa) {
s[x]=;int maxs=;
ren if(to[i]!=fa&&!vis[to[i]]) {
getroot(to[i],x);
s[x]+=s[to[i]];
maxs=max(maxs,s[to[i]]);
}
f[x]=max(size-s[x],maxs);
if(f[x]<f[rt]) rt=x;
}
int fa[maxn];
void solve(int x,int F) {
vis[x]=;fa[x]=F;
ren if(!vis[to[i]]) {
f[]=size=s[to[i]];getroot(to[i],rt=);
solve(rt,x);
}
}
Node *root[maxn],*root2[maxn];
void turn_on(int x) {
insert(root[x],);
for(int i=x;fa[i];i=fa[i]) {
int D=dist(x,fa[i]);
insert(root[fa[i]],D);
insert(root2[i],D);
}
}
int query(int x,int v) {
int ans=query(root[x],++v);
for(int i=x;fa[i];i=fa[i]) {
int D=dist(x,fa[i]);
ans+=query(root[fa[i]],v-D)-query(root2[i],v-D);
}
return ans;
}
int mark[maxn];
int main() {
n=read();int k=read();
rep(i,,n) root[i]=root2[i]=null;
rep(i,,n) AddEdge(read(),read(),read());
dfs(,);pre();
f[]=size=n;getroot(,rt=);
solve(rt,);
rep(i,,n) turn_on(i);
rep(i,,n) {
int l=,r=<<,mid;
while(l<r) if(query(i,mid=l+r>>)>k) r=mid; else l=mid+;
printf("%d\n",l);
}
return ;
}

BZOJ4317: Atm的树的更多相关文章

  1. [BZOJ2051]A Problem For Fun/[BZOJ2117]Crash的旅游计划/[BZOJ4317]Atm的树

    [BZOJ2051]A Problem For Fun/[BZOJ2117]Crash的旅游计划/[BZOJ4317]Atm的树 题目大意: 给出一个\(n(n\le10^5)\)个结点的树,每条边有 ...

  2. BZOJ4317: Atm的树+2051+2117

    BZOJ4317: Atm的树+2051+2117 https://lydsy.com/JudgeOnline/problem.php?id=4317 分析: 二分答案之后就变成震波那道题了. 冷静一 ...

  3. 【BZOJ4317】Atm的树 动态树分治+二分+线段树

    [BZOJ4317]Atm的树 Description Atm有一段时间在虐qtree的题目,于是,他满脑子都是tree,tree,tree…… 于是,一天晚上他梦到自己被关在了一个有根树中,每条路径 ...

  4. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  5. 我眼中的Linux设备树(二 节点)

    二 节点(node)的表示首先说节点的表示方法,除了根节点只用一个斜杠"/"表示外,其他节点的表示形式如"node-name@unit-address".@前边 ...

  6. BZOJ4317Atm的树&BZOJ2051A Problem For Fun&BZOJ2117[2010国家集训队]Crash的旅游计划——二分答案+动态点分治(点分树套线段树/点分树+vector)

    题目描述 Atm有一段时间在虐qtree的题目,于是,他满脑子都是tree,tree,tree…… 于是,一天晚上他梦到自己被关在了一个有根树中,每条路径都有边权,一个神秘的声音告诉他,每个点到其他的 ...

  7. Linux设备树(二 节点)

    二 节点(node)的表示 首先说节点的表示方法,除了根节点只用一个斜杠“/”表示外,其他节点的表示形式如“node-name@unit-address”.@前边是节点名字,后边是节点地址.节点名字的 ...

  8. 蓝桥杯 生命之树【树状dp】

    生命之树 在X森林里,上帝创建了生命之树. 他给每棵树的每个节点(叶子也称为一个节点)上, 都标了一个整数,代表这个点的和谐值. 上帝要在这棵树内选出一个非空节点集S, 使得对于S中的任意两个点a,b ...

  9. [蓝桥杯2015初赛]生命之树(树状dp)

    在X森林里,上帝创建了生命之树.他给每棵树的每个节点(叶子也称为一个节点)上,都标了一个整数,代表这个点的和谐值.上帝要在这棵树内选出一个非空节点集S,使得对于S中的任意两个点a,b,都存在一个点列 ...

随机推荐

  1. vue控制台报错

    1. TypeError: Cannot read property '_withTask' of undefined 这是因为引用找不到导致的,比如: <button @click='aaa' ...

  2. Windows平台上谷歌浏览器损害电池

    From:http://www.cnblogs.com/killerlegend/p/3909208.html Author:KillerLegend Date:2014.8.13 事情是这样的,我的 ...

  3. SQL语句(十)查询结果排序

    查询结果排序 使用ORDER BY 子句 SELECT <列名列表> FROM <表名> [WHERE 条件] ORDER BY <字段名1> [ASC|DESC] ...

  4. [转载]为什么有些MP4文件在Chrome浏览器上播放不了?

    http://blog.sina.com.cn/s/blog_6bb7ebcc0101c2ja.html Chrome浏览器支持HTML5,它支持原生播放部分的MP4格式(不用通过Flash等插件). ...

  5. HDU 2049 不容易系列之(4)——考新郎 (错排+组合)

    题目链接. Problem Description 国庆期间,省城HZ刚刚举行了一场盛大的集体婚礼,为了使婚礼进行的丰富一些,司仪临时想出了有一个有意思的节目,叫做"考新郎",具体 ...

  6. 乘法逆元(P3811)(四种方法)

    适合单个的,费马小定理,exgcd,都是不错的选择,利用积性函数的方法和欧拉筛的方法适合批量求,但是论时间和空间的话,还是积性函数的方法比较好用,线性的. 题目链接:https://www.luogu ...

  7. JS判断客户浏览器是否是IE8浏览器、jQuery判断浏览器内核

    今天在使用encharts的时候由于要兼容IE8,所以最终决定在非IE8浏览器使用encharts,在IE8使用amcharts.于是需要使用JS判断使用的浏览器版本: function IEVers ...

  8. SqlMapConfig.xml全局配置文件介绍——(四)

    ----------mybatis的全局配置文件SqlMapConfig.xml,配置内容如下:----------- properties(属性) settings(全局配置参数) typeAlia ...

  9. http和socket之长连接和短连接区别【转】

    转自:https://blog.csdn.net/mengyafei43/article/details/25195445 TCP/IP TCP/IP是个协议组,可分为三个层次:网络层.传输层和应用层 ...

  10. MySQL binlog导入失败

    一个同事问我,说他用innobackupex恢复数据后用mysqlbinlog导入增量数据时,发现数据没有导入进去并且也没有报错. mysqlbinlog /u01/mysql_py/database ...