首页 > 其他分享 >线段树合并的复杂度

线段树合并的复杂度

时间:2023-09-18 23:00:58浏览次数:41  
标签:rt return int 复杂度 合并 mer 线段

线段树合并的时间复杂度是 \(O(m\log n)\) 的(\(m\) 为插入次数)。

int mer(int x,int y){
    if(!x||!y)return x^y; t[x]+=t[y];
    return L[x]=mer(L[x],L[y]),R[x]=mer(R[x],R[y]),x;
}

因为每个点只会在自己被删除(情况 1)或父亲被删除且自己未删除的(即合并时另一个子树为空,情况 2)情况下被枚举。(被删除指的是在以后的线段树合并中不会被枚举到)。

情况 1 显然是 \(O(m\log n)\) 的,情况 2 只会在父亲被删除时才会被枚举,所以也是 \(O(m\log n)\) 的。所以整体复杂度为 \(O(m\log m)\)。

所以在树上用线段树合并是有时间复杂度保障的,大胆使用即可(常树较大)。

当题目的内存为 \(\texttt{128MB}\) 或 \(\texttt{256MB}\) 时建议加上垃圾回收,避免因为卡内存造成的 \(\texttt{MLE}\) 惨案。

P3605 [USACO17JAN] Promotion Counting P

随便找的一个简单题,直接线段树合并、区间询问即可。

// qwq
#include <bits/stdc++.h>
using namespace std;
constexpr int N=1e5+12;
int L[N*100],R[N*100],cnt,t[N*100];
int a[N],rt[N],ans[N],n;
vector<int>e[N];
void ins(int& k,int l,int r,int x){
    if(!k)k=++cnt;t[k]++;
    if(l==r)return;int mid=l+r>>1;
    if(x<=mid)ins(L[k],l,mid,x);
    else      ins(R[k],mid+1,r,x);
}
int ask(int k,int l,int r,int x,int y){
    if(x>y||l>r||l>y||x>r)return 0;
    if(l>=x&&r<=y)return t[k];int mid=l+r>>1;
    return ask(L[k],l,mid,x,y)+ask(R[k],mid+1,r,x,y);
}
int mer(int x,int y){
    if(!x||!y)return x^y; t[x]+=t[y];
    return L[x]=mer(L[x],L[y]),R[x]=mer(R[x],R[y]),x;
}
void dfs(int u){
    ins(rt[u],1,1e9,a[u]);
    for(int v:e[u])dfs(v),rt[u]=mer(rt[u],rt[v]);
    ans[u]=ask(rt[u],1,1e9,a[u]+1,1e9);
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)cin>>a[i];
    for(int i=2,x;i<=n;i++)cin>>x,e[x].push_back(i);
    dfs(1);
    for(int i=1;i<=n;i++)cout<<ans[i]<<'\n';
    return 0;
}

标签:rt,return,int,复杂度,合并,mer,线段
From: https://www.cnblogs.com/dadidididi/p/17713382.html

相关文章

  • 合并果子题解-C++ STL priority_queue容器的使用
    说明:本博文关于priority_queue容器的说明来源于www.cnblogs.com/fusiwei/p/11823053.html本人是刚刚接触算法竞赛的萌新,如果有大佬发现了错误,还望指出(真的有人会看本蒟蒻的博文吗)这是我的第一篇博文,更多是作为测试以后会将博客作为笔记记录学习的体会基本概念priority_queu......
  • 关于pta上6-2 两个有序链表序列的合并
    这是在dev上的源代码,C语言#include<stdio.h>#include<stdlib.h>typedefintElementType;typedefstructNode*PtrToNode;structNode{ElementTypeData;PtrToNodeNext;};typedefPtrToNodeList;ListRead();/*细节在此不表*/voidPrint(List......
  • Excel 三列数据如何合并为一列
    1、用公式法:假定ABC三列数据要合并,请在D1输入公式=A1&B1&C1,鼠标放在D1单元格右下角,出现十字叉后双击。如果要删除原有三列数据,请选定D列==复制==选择性粘贴==数值,再删除A、B、C三列 2. 用函数法:使用TEXTJOIN()函数,此方法可以设置分隔符。......
  • 主定理(时间复杂度计算方式)
    MasterTheorem用途一种用于计算递归时间复杂度的定理。比如对于一个时间复杂度递推式:\(T(n)=T(n/2)+O(n)\),可以浅显地看出它的复杂度为\(O(nlog_2n)\),因为我们这样子的递归写了太多次了。但我们可以看到\(T(n)=4T(n/2)+n\),它的复杂度是多少?也是\(O(nlog_2n)\)?当在问出......
  • 【线段树合并、虚树】P5327 [ZJOI2019] 语言
    终于1kAC了家人,感动吧。贺了很久,很累。前置题目:P3320[SDOI2015]寻宝游戏虚树的边权和:\[\sumdep_{a_x}-\sum_{x<n}dep_{a_x,a_{x+1}}-dep_{a_{1},a_{n}}\]考虑转化贡献,求过该点的链的并,最后再除以二即可。那么我们可以考虑维护以该点的子树的所有关键点以及......
  • 代码提交和分支合并
              ......
  • poj 2528 Mayor's posters 线段树+离散化
    离散化处理要注意+1(看了HH大牛的博客懂的,以前自己的代码是不对的)例如数据:1311013610这样,普通离散化处理 {13610},然后此程序会操作成点染色,于是结果为2,但正确答案为3;HH大牛给出一种离散化方法:     如果相邻数字间距大于1的话,在其中加上任意一个数字,比如加......
  • 可持久化非确定状态AC自动分块维护线段平衡仙人掌优化最小费用最大流预处理混合图上莫
    P8946TheLostSymbol这种类型的dp的特点就是大部分转移形如\(f(i,j)\rightarrowf(i+1,j+1)\)之类的,并且当以上转移出现时原数组被清空,这就可以用一个deque来维护,然后对于全局赋值/全局加,需要对每个位置维护一个时间戳,并记录上一次赋值/加是什么时候,以便标记下传。(貌似......
  • OpenAI: 如何合并多个mp4视频
    1.确保你已经安装了FFmpeg工具。你可以从官方网站(https://ffmpeg.org/)下载适合你操作系统的版本,或者使用包管理器进行安装。2.把要合并的MP4视频文件放入同一个文件夹中,以便于处理。3.在该文件夹中创建一个文本文件,例如命名为input.txt,用来列出所有要合并的视频文件的路径。......
  • Git分支合并(merge)时忽略dist文件
    Git分支合并(merge)时忽略dist文件Git分支合并(merge)时忽略某个文件或者目录​前端项目不同分支dist文件合并到其他分支有很多冲突操作步骤1.定义虚拟合并策略gitconfig--globalmerge.ours.drivertrue其他配置可参考Git配置2.编辑规则文件编辑根目录下的.gita......