翻译

题目描述

给你一棵树,和它的树根 $P$,并且节点从 $1\rightarrow n$ 编号,现在定义 $f(i)$ 为 $i$ 的子树中,节点编号小于 $i$ 的节点的个数。

输入格式

有多组数据 (不超过 10 组),对于每组数据:
第一行两个整数 $n,p$ $(n\le 10^5)$ 表示树有 $n$ 个节点,树根是 $p$。
接下来的 $n-1$ 行,每行两个整数,代表一条树边。
输入以两个零作为结束。

输出格式

对于每组测试数据,输出一行 $n$ 个整数 $f(1),f(2)......f(n)$,每两个数字之间以一个空格分格。

解题思路

显然,我们想要求 $f(i)$ 的话,只需要对其子树进行统计,而有不能够每一次都去遍历一遍,那样一定会超时。我们可以用 dfs 序先对整棵树进行处理,dfs 序可以将一个点的子树的编号放在一个区间内。然后用线段树进行求解 (如果暴力的在区间内统计的话,会 TLE,实锤),按编号从小到大将点的影响加到线段树中,边查询边更新。这样总时间复杂度是 $\text{O}(n\log n)$,显然可过。
要注意输出格式,每一行最后一个数字后面不能加空格。

附上代码

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int maxn = 2e5+;
inline int read() {
int x = , f = ; char c = getchar();
while (c < '' || c > '') {if(c == '-') f = -; c = getchar();}
while (c <= '' && c >= '') {x = x* + c-''; c = getchar();}
return x * f;
}
int n, rt, head[maxn], Index, L[maxn], R[maxn], cnt;
struct edge {
int nxt, to;
}ed[maxn];
inline void addedge(int x, int y) {
ed[++cnt].nxt = head[x], ed[cnt].to = y, head[x] = cnt;
ed[++cnt].nxt = head[y], ed[cnt].to = x, head[y] = cnt;
}
inline void dfs(int x, int fr) {
L[x] = ++ Index;
for(int i=head[x]; i; i=ed[i].nxt) {
if(ed[i].to == fr) continue;
dfs(ed[i].to, x);
}
R[x] = Index;
}
struct TREE {
int l, r, sum;
}tree[maxn << ];
struct Segment_Tree {
#define Lson (k << 1)
#define Rson ((k << 1) + 1)
inline void build(int k, int ll, int rr) {
tree[k].l = ll, tree[k].r = rr;
tree[k].sum = ;
if(tree[k].l == tree[k].r) return ;
int mid = (tree[k].l + tree[k].r) >> ;
build(Lson, ll, mid);
build(Rson, mid+, rr);
}
inline void update(int k, int pos, int num) {
if(tree[k].l == tree[k].r && tree[k].l == pos) {
tree[k].sum += num;
return ;
}
int mid = (tree[k].l + tree[k].r) >> ;
if(pos <= mid) update(Lson, pos, num);
else update(Rson, pos, num);
tree[k].sum = tree[Lson].sum + tree[Rson].sum;
}
inline int query(int k, int l, int r) {
int res = ;
if(l <= tree[k].l && r >= tree[k].r)
return tree[k].sum;
int mid = (tree[k].l + tree[k].r) >> ;
if(l <= mid) res += query(Lson, l, r);
if(r > mid) res += query(Rson, l, r);
return res;
}
}T;
int main() {
while (scanf("%d%d", &n, &rt) == ) {
if(n == && rt == ) return ;
memset(head, , sizeof(head));
cnt = , Index = ;
int x, y;
for(int i=; i<n; i++) {
x = read(), y = read();
addedge(x, y);
}
dfs(rt, );
T.build(, , n);
for(int i=; i<=n; i++) {
printf("%d", T.query(, L[i], R[i]));
T.update(, L[i], );
if(i == n) printf("\n");
else printf(" ");
}
}
}

「 HDOJ P3887 」 Counting Offspring的更多相关文章

  1. 「日常训练」 Counting Cliques(HDU-5952)

    题意与分析 题源:2016ACM/ICPC沈阳现场赛. 这题让我知道了什么是团,不过最恶心的还是这题的数据了,卡了无数次- - 解决方法是维护一个G数组,不能去遍历邻接矩阵.至少我改了这么一个地方就过 ...

  2. 「 HDOJ P2227 」 Find the nondecreasing subsequences

    # 题目大意 就是找不下降子序列的个数. # 解题思路 一开始想着先离散化,然后再做个 $dp$,发现用 $dp$ 的话时间复杂度是 $\text{O}(n^2)$ 的,稳稳超时. 这里说说 $dp$ ...

  3. 「算法笔记」树形 DP

    一.树形 DP 基础 又是一篇鸽了好久的文章--以下面这道题为例,介绍一下树形 DP 的一般过程. POJ 2342 Anniversary party 题目大意:有一家公司要举行一个聚会,一共有 \ ...

  4. 前端构建工具之gulp(一)「图片压缩」

    前端构建工具之gulp(一)「图片压缩」 已经很久没有写过博客了,现下终于事情少了,开始写博吧 今天网站要做一些优化:图片压缩,资源合并等 以前一直使用百度的FIS工具,但是FIS还没有提供图片压缩的 ...

  5. fir.im Weekly - 如何打造 Github 「爆款」开源项目

    最近 Android 转用 Swift 的传闻甚嚣尘上,Swift 的 Github 主页上已经有了一次 merge>>「Port to Android」,让我们对 Swift 的想象又多 ...

  6. 更新日志 - fir.im「高级统计」功能上线

    距离 2016 年到来只剩 10 个日夜,fir.im 也准备了一些新鲜的东西,比如「高级统计」功能和「跳转应用商店」功能,帮助你更好地管理.优化应用,欢迎大家试用反馈:) 新增高级统计功能 这次更新 ...

  7. Notepad++ 开启「切分窗口」同时检视、比对两份文件

    Notepad++ 是个相当好用的免费纯文本编辑器,除了内建的功能相当多之外,也支持外挂模块的方式扩充各方面的应用.以前我都用 UltraEdit 跟 Emeditor,后来都改用免费的 Notepa ...

  8. hdu 3887 Counting Offspring dfs序+树状数组

    Counting Offspring Time Limit: 15000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Othe ...

  9. 「zigbee - 1」工欲善其事必先利其器 - IAR for 8051 IDE customization

    最近在实验室做一些 Zigbee 相关的事情,然而一直没在博客上记录啥东西,也不像原来在公司有动力在 Confluence wiki 上扯东扯西.直到前些阵子,跑到 feibit 论坛上(国内较大的一 ...

随机推荐

  1. Eclipse中,open declaration;open implementation;open super implementation的区别

    open declaration:是打开该方法的接口文件(一般没实在意义,只是简单一句):open implementation:是打开具体实现该方法的类文件(具体逻辑的处理地方,方法的主要实现的地方 ...

  2. Swift里计数相关的小细节

    Swift里对于字符串这些引入了index型,相对其他语言而言字符操作更安全了,但是问题就是一不注意搞错范围就会有各种离奇的bug. 在讲主题前,先说个小细节. Swift里非常严密的定义了一大堆字符 ...

  3. git 基本命令详细解释

    创建: 2017-04-05 17:04:03         2017-04-24 更新: 2017-05-16 更新: 2017-06-27  完善git remote add  更新: 2017 ...

  4. Codeforces 快速竞技#4

    快速竞技#4 A–Duff and Meat588A = =这题不知道怎么写题解了.. 直接上code---. #include<bits/stdc++.h> #include<st ...

  5. SQL中进行转列的几种方式

    SQL中进行转列 在很多笔试的程序员中会有很多写SQL的情况,其中很多时候会考察行转列.那么这个时候如果能写出来几种行转列的SQL,会给面试官留下比较好的印象. 以下是这次sql转换的表结构以及数据 ...

  6. 1391:局域网(net)

    [题目描述] 某个局域网内有n(n≤100)台计算机,由于搭建局域网时工作人员的疏忽,现在局域网内的连接形成了回路,我们知道如果局域网形成回路那么数据将不停的在回路内传输,造成网络卡的现象.因为连接计 ...

  7. hdu1232 畅通工程 基础并查集

    #include <cstdio> #include <cstring> #include <algorithm> #include <cstdlib> ...

  8. iOS 获取当前响应链的First Responder (Swift)

    import UIKit private weak var currentFirstResponder: AnyObject? extension UIResponder { static func ...

  9. Rsync 实现远程同步

    介绍 rsync命令是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件.rsync使用所谓的“rsync算法”来使本地和远程两个主机之间的文件达到同步,这个算法只传送两个文件的不同部 ...

  10. Python入门小练习 002 批量下载网页链接中的图片

    我们常常需要下载网页上很多喜欢的图片,但是面对几十甚至上百张的图片,一个一个去另存为肯定是个很差的体验. 我们可以用urllib包获取html的源码,再以正则表达式把匹配的图片链接放入一个list中, ...