Tree

题目描述

给你一棵TREE,以及这棵树上边的距离.问有多少对点它们两者间的距离小于等于K

输入输出格式

输入格式:

N(n<=40000) 接下来n-1行边描述管道,按照题目中写的输入 接下来是k

输出格式:

一行,有多少对点之间的距离小于等于k


淀粉质感觉怎么写都不好看啊,迷。。

实现方法非常多。

大概思路:

对每一个子树的二层子节点进行遍历,处理每个点所属的二层子节点和到根节点的距离

以到根节点的距离为关键字排序,从两边进行扫描

如果当前满足,答案就加上\(r-l-\)和\(l\)属于同一颗二层子节点的数的数量,后者可以直接拿一个桶边扫描边维护

这个每次可以统计答案的区间是逐渐缩小的,有单调性。每次统计时候的意义是对\(l\)位置的节点,有多个点可以跨过根和它配对。

然后递归处理子树的答案。注意每次选择重心作为根节点保证复杂度。


Code:

#include <cstdio>
#include <algorithm>
const int N=4e4+10;
const int inf=0x3f3f3f3f;
int head[N],to[N<<1],Next[N<<1],edge[N<<1],cnt;
void add(int u,int v,int w)
{
to[++cnt]=v,Next[cnt]=head[u],edge[cnt]=w,head[u]=cnt;
}
struct node
{
int b,d;
node(){}
node(int b,int d){this->b=b,this->d=d;}
bool friend operator <(node n1,node n2){return n1.d<n2.d;}
}a[N];
int mi,id,ans,n,m,k,coun[N],siz[N],del[N];
int max(int x,int y){return x>y?x:y;}
void get_g(int now,int fa,int su)
{
siz[now]=1;int mx=0;
for(int i=head[now];i;i=Next[i])
{
int v=to[i];
if(!del[v]&&v!=fa)
{
get_g(v,now,su);
mx=max(mx,siz[v]);
siz[now]+=siz[v];
}
}
mx=max(mx,su-siz[now]);
if(mx<mi) mi=mx,id=now;
}
void dfs(int now,int fa,int anc,int dis)
{
a[++cnt]=node(anc,dis);
siz[now]=1;
for(int i=head[now];i;i=Next[i])
{
int v=to[i];
if(!del[v]&&v!=fa)
dfs(v,now,anc,dis+edge[i]),siz[now]+=siz[v];
}
}
void divide(int now,int su)
{
mi=inf,cnt=0;
get_g(now,0,su);
now=id;del[now]=1;
a[++cnt]=node(now,0),coun[now]=1;
for(int i=head[now];i;i=Next[i])
{
int v=to[i];
if(!del[v])
dfs(v,now,v,edge[i]),coun[v]=siz[v];
}
std::sort(a+1,a+1+cnt);
int l=1,r=cnt;
while(l<r)
{
while(l<r&&a[r].d+a[l].d>k) --coun[a[r--].b];
if(a[r].d+a[l].d<=k) ans+=r-l-coun[a[l].b]+1;
--coun[a[l++].b];
}
for(int i=head[now];i;i=Next[i])
{
int v=to[i];
if(!del[v])
divide(v,siz[v]);
}
}
int main()
{
scanf("%d",&n);
for(int u,v,w,i=1;i<n;i++)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w),add(v,u,w);
}
scanf("%d",&k);
divide(1,n);
printf("%d\n",ans);
return 0;
}

2018.9.15

淀粉质模板 Tree的更多相关文章

  1. loj2497 [PA2017]Banany(动态淀粉质)

    link 给定一棵树,点有点权,边有边权,你每次修改一个点点权或者是修改一个边边权 你一开始在1号点,你每次改节点之后你需要移动到另一个节点,满足这个节点权值减去路径长度最大(下一次从这个节点移动)如 ...

  2. 【JZOJ6368】质树(tree)

    description 大神 wyp 手里有棵二叉树,每个点有一个点权.大神 wyp 的这棵树是质树,因为 随便找两个不同的点 u, v,只要 u 是 v 的祖先,都满足 u 和 v 的点权互质. 现 ...

  3. 动态淀粉质(划掉)题单&简要题解

    简介 动态点分治的思想:还不太清楚诶怎么办. 大概是通过降低树高来降低每次修改和询问的复杂度吧,还可以把树上一个连通块的信息统计到一个点(重心)上.具体实现方式和普通的静态点分治没有太大的区别,只是把 ...

  4. [POJ1741]Tree(点分治模板)

    传送门 良心解析 其实以前在求某段序列上的区间统计问题时就碰到过类似于这样的思想. 当时的区间统计问题思路大致是这样: 选取一个点作为中间点,从这个点的左边和右边统计出满足条件的点对.然后当前的中间点 ...

  5. 【题解】Digit Tree

    [题解]Digit Tree CodeForces - 716E 呵呵以为是数据结构题然后是淀粉质还行... 题目就是给你一颗有边权的树,问你有多少路径,把路径上的数字顺次写出来,是\(m\)的倍数. ...

  6. 【模板】P3806点分治1

    [模板]P3806 [模板]点分治1 很好的一道模板题,很无脑经典. 讲讲淀粉质吧,很营养,实际上,点分治是树上的分治算法.根据树的特性,树上两点的路径只有一下两种情况: 路径经过根\((*)\) 路 ...

  7. Hello Kiki(中国剩余定理——不互质的情况)

    Hello Kiki Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...

  8. P3806 【模板】点分治1

    一道淀粉质的模版题,开始是暴力 #include <bits/stdc++.h> #define up(i,l,r) for(register int i = (l); i <= ( ...

  9. P4178 Tree

    最简单的点分治 淀粉质的思想: “分而治之”,缩小问题规模,合并求解: #include<cstdio> #include<cmath> #include<cstring ...

随机推荐

  1. C++的队列和pair

    C++队列的成员函数: back()返回最后一个元素 empty()如果队列空则返回真 front()返回第一个元素 pop()删除第一个元素 push()在末尾加入一个元素 size()返回队列中元 ...

  2. 出门旅行(tour)

    出门旅行(tour) 题目描述: 在神奇的 oi 国度,有 n 个城市 m 条双向道路,每条道路连接了两个不同的城市.寒假到了,小 S 决定出门旅游一趟.因为以往跟团旅游多了,这次小 S 决定自驾游. ...

  3. 基于mybatis设计简单信息管理系统1

    驼峰式命名法 骆驼式命名法就是当变量名或函数名是由一个或多个单词连结在一起,而构成的唯一识别字时,第一个单词以小写字母开始:第二个单词的首字母大写或每一个单词的首字母都采用大写字母,例如:myFirs ...

  4. 你们知道SEO每天都在做什么吗?

    医院也有做SEO的,专门负责医院网站优化工作,那么医院的SEO每天都做什么呢?偶然见到一篇文章,转载来分享给大家.感觉写的很实在. 大凡做seo工作的人都知道seo工作者每天都要做大量的外链,像有些个 ...

  5. web前端工程师面试技巧 常见问题解答

    web前端工程师面试技巧 常见问题解答 每年的春招是各企业需求人才的黄金时期,不少的前端大牛或者前端新手在面试时候不知道怎么来回答面试官的问题,下面来看下我转载的这篇文章吧,希望对从事前端工作的你有所 ...

  6. 1016-06-首页20-封装工具条---UITableView控件距离顶部的间距问题----cell选中时的背景颜色设置

    一.设置UITableView里面的顶部 cell 距离顶部的间距的三种方式: 方法 1. 直接设置: self.tableView.contentInset = UIEdgeInsetsMake(H ...

  7. (洛谷)P2709 小B的询问

    题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L..R]中的重 ...

  8. python-12正则表达式

    import re #re.search方法 re.search 扫描整个字符串并返回第一个成功的匹配. re.match('com', 'www.runoob.com') #匹配失败 None re ...

  9. Python 装饰器执行顺序迷思

    Table of Contents 1. 探究多个装饰器执行顺序 1.1. 疑问 1.2. 函数和函数调用的区别 1.3. 装饰器函数在被装饰函数定义好后立即执行 1.4. 疑问的解释 2. 参考资料 ...

  10. AD高级规则设置

    inpolygon 是所有的覆铜 ispad 是焊盘到焊盘的间距 IsVia 过孔间距 ispad and InComponent('S1')    设置某个器件的焊盘间距规则 ispad and H ...