HDU
来源:互联网 发布:怎么在淘宝上办学生证 编辑:程序博客网 时间:2024/05/17 03:39
Counting Offspring
HDU - 3887You are given a tree, it’s root is p, and the node is numbered from 1 to n. Now define f(i) as the number of nodes whose number is less than i in all the succeeding nodes of node i. Now we need to calculate f(i) for any possible i.
The first line contains two integers n (0<n<=10^5) and p, representing this tree has n nodes, its root is p.
Following n-1 lines, each line has two integers, representing an edge in this tree.
The input terminates with two zeros.
15 77 107 17 97 37 410 1414 214 139 119 66 56 83 153 120 0
0 0 0 0 0 1 6 0 3 1 0 0 0 2 0
HDU - 3887
题意:问对于每个节点,它的子树上标号比它小的点有多少个。
dfs序+线段树
关于dfs序:
dfs序是处理树上问题很重要的一个工具,主要能够解决对于一个点,它的子树上的一些信息的维护,即用来处理子树的问题。 dfs序一般开的空间是n,因为只在入的地方时间戳++,出来的地方时间戳没有额外的++,线段树的每个节点应当是时间戳。
这里,因为点在它的子树上,所以在线段树中,故在它的两个时间戳的区间内([p1[i],p2[i]),所以我们只需要从小到大考虑,它的区间里有多少个点已经放入,然后再把它放入即可。
时间复杂度 O(nlogn)
空间复杂度 O(4*n)
#include <iostream>#include <cstdio>#include <vector>#include <cstring>using namespace std;typedef long long LL;const int MAXN = 1e5 + 8;vector<int> sons[MAXN];//dfs序int p1[MAXN], p2[MAXN], ti = 0;int dfsnum[MAXN]; //这个按情况是否需要。inline void get_dfs_list(int u, int fa){ p1[u] = ++ti; dfsnum[ti] = u; // int sz = sons[u].size(), i, v; for(i = 0; i < sz; i++){ v = sons[u][i]; if(v == fa) continue; get_dfs_list(v, u); } p2[u] = ti;}//线段树int sum[4*MAXN];int size;inline void pushup(int Ind){ sum[Ind] = sum[Ind<<1] + sum[(Ind<<1) + 1];}inline int _Query(int a, int b, int l, int r, int Ind){ if(a <= l && b >= r) return sum[Ind]; int mid = (l+r)>>1; int ret = 0; if(a <= mid) ret += _Query(a, b, l, mid, Ind<<1); if(b > mid) ret += _Query(a, b, mid + 1, r, (Ind<<1) + 1); return ret;}inline void _Modify(int a, int l, int r, int Ind, int d){ if(l == r && l == a){ sum[Ind] = d; return; } int mid = (l+r)>>1; if(a <= mid) _Modify(a, l, mid, Ind<<1, d); else _Modify(a, mid + 1, r, (Ind<<1) + 1, d); pushup(Ind);}inline int Query(int a, int b) {return _Query(a, b, 1, size, 1);}inline void Modify(int a, int d){return _Modify(a, 1, size, 1, d);}int main(){ #ifdef LOCAL freopen("a.txt", "r", stdin); //freopen("a.out", "w", stdout); int T = 1; while(T--){ #endif // LOCAL ios::sync_with_stdio(false); cin.tie(0); int n, p, i, u, v, root; while(cin >> n >> p){ if(n == 0 && p == 0) break; for(i = 1; i < n; i++){ cin >> u >> v; sons[u].push_back(v); sons[v].push_back(u); } root = p; ti = 0; get_dfs_list(root, -1); size = ti; memset(sum, 0, sizeof sum); for(i = 1; i <= n; i++){ cout << Query(p1[i], p2[i]); if(i == n) cout << "\n"; else cout << " "; Modify(p1[i], 1); sons[i].clear(); } } #ifdef LOCAL cout << endl; } #endif // LOCAL return 0;}
------from ProLights
Thank you!
阅读全文
0 0
- hdu
- hdu
- HDU
- hdu ()
- hdu
- hdu
- HDU
- HDU
- hdu
- hdu
- HDU
- Hdu
- hdu
- hdu-
- hdu
- hdu
- hdu
- HDU
- Harris特征检测与SIFT特征点描述
- android studio 6.0以上运行时权限
- Spark之 spark简介、生态圈详解
- Hibernate 实体类注解详解
- 利用Winform Gmail 发送信件
- HDU
- Python爬虫爬取知乎小结
- codeforces 869BThe Eternal Immortality
- sso单点登录
- C#语言-输入三角形或者长方形边长,计算其周长和面积并输出
- 生活小记22
- 输入一个链表,从尾到头打印链表每个节点的值
- 事件
- php gzuncompress data error问题解决