题意

题目链接

Sol

线段树合并板子题,目前我看到两种写法,分别是这样的。

前一种每次需要新建一个节点,空间是\(O(4nlogn)\)

后者不需要新建,空间是\(O(nlogn)\)(面向数据算空间你懂得),但是需要离线,因为共用节点的缘故,之后的修改可能会修改到不需要修改的节点(好绕啊);

这题就是把向上向下的贡献分开算,然后移一下项发现只与深度有关

可以直接二维数点,也可以线段树合并

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. const int MAXN = 400000, SS = MAXN * 21;
  4. inline int read() {
  5. char c = getchar(); int x = 0, f = 1;
  6. while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
  7. while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
  8. return x * f;
  9. }
  10. int N, p[MAXN], fa[MAXN], root[MAXN], tot, ans[MAXN];
  11. vector<int> v[MAXN];
  12. int ls[SS], rs[SS], sum[SS];
  13. void insert(int &k, int l, int r, int p, int v) {
  14. if(!k) k = ++tot;
  15. sum[k]++;
  16. if(l == r) return ;
  17. int mid = l + r >> 1;
  18. if(p <= mid) insert(ls[k], l, mid, p, v);
  19. else insert(rs[k], mid + 1, r, p, v);
  20. }
  21. int Query(int k, int l, int r, int ql, int qr) {
  22. if(ql <= l && r <= qr) return sum[k];
  23. int mid = l + r >> 1;
  24. if(ql > mid) return Query(rs[k], mid + 1, r, ql, qr);
  25. else if(qr <= mid) return Query(ls[k], l, mid, ql, qr);
  26. else return Query(ls[k], l, mid, ql, qr) + Query(rs[k], mid + 1, r, ql, qr);
  27. }
  28. int Merge(int x, int y) {
  29. if(!x || !y) return x ^ y;
  30. ls[x] = Merge(ls[x], ls[y]);
  31. rs[x] = Merge(rs[x], rs[y]);
  32. sum[x] += sum[y];
  33. return x;
  34. }
  35. void dfs(int x) {
  36. for(int i = 0; i < v[x].size(); i++) {
  37. int to = v[x][i]; dfs(to);
  38. root[x] = Merge(root[x], root[to]);
  39. }
  40. ans[x] = Query(root[x], 1, N, p[x] + 1, N);
  41. insert(root[x], 1, N, p[x], 1);
  42. }
  43. void Des() {
  44. static int date[MAXN], num = 0;
  45. for(int i = 1; i <= N; i++) date[++num] = p[i];
  46. sort(date + 1, date + num + 1);
  47. num = unique(date + 1, date + num + 1) - date - 1;
  48. for(int i = 1; i <= N; i++) p[i] = lower_bound(date + 1, date + N + 1, p[i]) - date;
  49. }
  50. int main() {
  51. N = read();
  52. for(int i = 1; i <= N; i++) p[i] = read();
  53. Des();
  54. for(int i = 2; i <= N; i++) fa[i] = read(), v[fa[i]].push_back(i);
  55. dfs(1);
  56. for(int i = 1; i <= N; i++) printf("%d\n", ans[i]);
  57. return 0;
  58. }
  59. /*
  60. */

洛谷P3899 [湖南集训]谈笑风生(线段树合并)的更多相关文章

  1. luogu P3899 [湖南集训]谈笑风生 线段树合并

    Code: #include<bits/stdc++.h> #define maxn 300002 #define ll long long using namespace std; vo ...

  2. 洛谷P3521 [POI2011]ROT-Tree Rotation [线段树合并]

    题目传送门 Tree Rotation 题目描述 Byteasar the gardener is growing a rare tree called Rotatus Informatikus. I ...

  3. P3899 [湖南集训]谈笑风生 主席树

    #include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> ...

  4. [Luogu P3899] [湖南集训]谈笑风生 (主席树)

    题面 传送门:https://www.luogu.org/problemnew/show/P3899 Solution 你们搞的这道题啊,excited! 这题真的很有意思. 首先,我们可以先理解一下 ...

  5. 主席树 || 可持久化线段树 || BZOJ 3653: 谈笑风生 || Luogu P3899 [湖南集训]谈笑风生

    题面:P3899 [湖南集训]谈笑风生 题解: 我很喜欢这道题. 因为A是给定的,所以实质是求二元组的个数.我们以A(即给定的P)作为基点寻找答案,那么情况分两类.一种是B为A的父亲,另一种是A为B的 ...

  6. 洛谷 P3373 【模板】线段树 2

    洛谷 P3373 [模板]线段树 2 洛谷传送门 题目描述 如题,已知一个数列,你需要进行下面三种操作: 将某区间每一个数乘上 xx 将某区间每一个数加上 xx 求出某区间每一个数的和 输入格式 第一 ...

  7. luogu P3899 [湖南集训]谈笑风生

    传送门 nmyzd,mgdhls,bnmbzdgdnlql,a,wgttxfs 对于一个点\(a\),点\(b\)只有可能是他的祖先或者在\(a\)子树里 如果点\(b\)是\(a\)祖先,那么答案为 ...

  8. P3899 [湖南集训]谈笑风生

    题目链接 https://www.lydsy.com/JudgeOnline/problem.php?id=3653 https://www.luogu.org/problemnew/show/P38 ...

  9. 洛谷P4556 雨天的尾巴 线段树

    正解:线段树合并 解题报告: 传送门! 考虑对树上的每个节点开一棵权值线段树,动态开点,记录一个max(num,id)(这儿的id,define了一下,,,指的是从小到大排QAQ 然后修改操作可以考虑 ...

随机推荐

  1. ReactNative学习笔记(七)Navigator的使用

    前言 Navigator主要用于ReactNative中的跳转,中文文档: http://reactnative.cn/docs/0.39/using-navigators.html 懒得打字介绍更多 ...

  2. 面试时遇到的题目。正则,replace()

    function Fn(str){ this.str = str; } Fn.prototype.format = function(){ var arg = arguments; var dd = ...

  3. Testing - 软件测试知识梳理 - 测试阶段

    估算 测试对软件工作量的估算的准确性 测试评估软件系统的状况的准确性 关注点: 不准确的估算 不适当的开发过程 不真实的状态报告 如何知道对工作量的估算是正确的 估算工作量的工具很容易出错 对软件工作 ...

  4. Testing - 软件测试知识梳理 - 基础概念

    测试是为了度量和提高被测试软件的质量,对测试软件进行工程设计.实施.维护的的整个生命周期过程. 仅仅发现Bug是测试的初步,而分析出根本原因推动问题的解决,却要有很深的功底. 不同的测试岗位从事不同的 ...

  5. 用O(1)的时间复杂度删除单链表中的某个节点

    给定链表的头指针和一个结点指针,在O(1)时间删除该结点.链表结点的定义如下: struct ListNode { int m_nKey; ListNode* m_pNext; }; 函数的声明如下: ...

  6. ABP实践(3)-ASP.NET Core 2.x版本(从创建实体到输出api)简单实现商品列表及增删改

    项目基于前两篇文章. 本章创建一个简单版的商品管理后台api,用到EF Core用code fist迁移数据创建数据库. 创建Goods实体 在领域层xxx.Core项目[新建文件夹Goods;文件夹 ...

  7. docker环境 宿主机和容器之间复制文件

    容器往宿主机:docker cp 3234234324234:/database_dump_bak/db_bak.dmp /home/test 宿主机往容器:docker cp wenjian_001 ...

  8. python selenium 对浏览器标签页进行关闭和切换

    1.关闭浏览器全部标签页 driver.quit() 2.关闭当前标签页(从标签页A打开新的标签页B,关闭标签页A) driver.close() 3.关闭当前标签页(从标签页A打开新的标签页B,关闭 ...

  9. Java工程师学习指南 初级篇

    Java工程师学习指南 初级篇 最近有很多小伙伴来问我,Java小白如何入门,如何安排学习路线,每一步应该怎么走比较好.原本我以为之前的几篇文章已经可以解决大家的问题了,其实不然,因为我之前写的文章都 ...

  10. zookeeper集群操作【这里只说明简单的操作步骤,zk的相关参数、说明请参考官方文档】

      本文版权归 远方的风lyh和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作.        [这里是在一台机器上搭建的 zk伪集群] 1.从官网下载下载zk http://apa ...