线段树综合学习笔记

1. 线段树分裂

【模板】线段树分裂

https://www.gxyzoj.com/d/gxyznoi/p/P223

采用和平衡树一样的方法,先求和,然后按线段树二分的写法即可

点击查看代码
#include<cstdio>
#include<algorithm>
#define ll long long
using namespace std;
const int N=2e5+5,M=4e6+5;
int n,m,ls[M],del[M],rs[M],rt[N],tot,cnt=1,dcnt;
ll val[M];
int newnode()
{if(dcnt) return del[dcnt--];return ++tot;
}
int update(int p,int l,int r,int x,ll v)
{if(!p) p=newnode();if(l==r){val[p]+=v;return p;}int mid=(l+r)>>1;if(x<=mid) ls[p]=update(ls[p],l,mid,x,v);else rs[p]=update(rs[p],mid+1,r,x,v);val[p]=val[ls[p]]+val[rs[p]];return p;
}
ll query(int p,int l,int r,int ql,int qr)
{if(!p) return 0;if(ql<=l&&qr>=r){return val[p];}int mid=(l+r)>>1;ll x=0;if(ql<=mid) x+=query(ls[p],l,mid,ql,qr);if(qr>mid) x+=query(rs[p],mid+1,r,ql,qr);return x;
}
void split(int x,int &y,ll k)
{if(!x) return;y=newnode();ll v=val[ls[x]];if(k>v) split(rs[x],rs[y],k-v);else swap(rs[x],rs[y]);if(k<v) split(ls[x],ls[y],k);val[y]=val[x]-k;val[x]=k;
}
void delt(int x)
{del[++dcnt]=x;val[x]=ls[x]=rs[x]=0;
}
int merge(int x,int y)
{if(!x||!y) return x+y;val[x]+=val[y];ls[x]=merge(ls[x],ls[y]);rs[x]=merge(rs[x],rs[y]);delt(y);return x;
}
int getans(int p,int l,int r,ll k)
{if(l==r) return l;int mid=(l+r)>>1;if(k<=val[ls[p]]) return getans(ls[p],l,mid,k);else return getans(rs[p],mid+1,r,k-val[ls[p]]);
}
int main()
{scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){int x;scanf("%d",&x);if(x) rt[1]=update(rt[1],1,n,i,x);}while(m--){int opt,p,a=0;ll l,r;scanf("%d%d%lld",&opt,&p,&l);if(opt==0){scanf("%lld",&r);++cnt;ll k1=query(rt[p],1,n,1,r),k2=query(rt[p],1,n,l,r);split(rt[p],rt[cnt],k1-k2);split(rt[cnt],a,k2);rt[p]=merge(rt[p],a);}if(opt==1){rt[p]=merge(rt[p],rt[l]);}if(opt==2){scanf("%lld",&r);rt[p]=update(rt[p],1,n,r,l);}if(opt==3){scanf("%lld",&r);printf("%lld\n",query(rt[p],1,n,l,r));}if(opt==4){if(query(rt[p],1,n,1,n)<l){printf("-1\n");continue;}printf("%d\n",getans(rt[p],1,n,l));}}return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/906343.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20242125 单嘉怡 实验二《Python程序设计》实验报告

20242125单嘉怡 2024-2025-2 《Python程序设计》实验二报告 课程:《Python程序设计》 班级:2421 姓名:单嘉怡 学号:20232401 实验教师:王志强 实验日期:2025年3月26日 必修/选修: 公选课 一.实验内容设计并完成一个完整的应用程序,完成加减乘除模等运算,功能多多益善。…

026 登录页-手机登录搭建-volar警告消除

这里什么也不写,把res删除 2、这样写 3、看看效果

20243116 实验二《Python程序设计》实验报告

20243116 2024-2025-2 《Python程序设计》实验二报告 课程:《Python程序设计》 班级: 2431 姓名: 陆翔轩 学号:20243116 实验教师:王志强 实验日期:2025年3月26日 必修/选修: 公选课 一、实验内容 1.设计并完成一个完整的应用程序,完成加减乘除模等运算,功能多多益善。…

基于Grafana使用官方模版查询Prometheus数据

grafana配置Prometheus作为数据源选择一个模版,导入到dashboards 模板地址 https://grafana.com/grafana/dashboards/ 选择Prometheus,选择一个适应版本的模版,记录ID 例如:1860 11074 8919查看dashboards

计算机二级之C++专业知识①

前排提醒:做选择题的时候不能用编译器,只能用脑子想 里面标了⭕的是新内容,最好把这一段好好看看1、C++概述 1.1 比较C和C++ C++相对于C语言最更本的变化是引入了类与对象的概念(最大改进也是这个) 面向对象思想:具有封装性(封装了数据和操作)、继承性、多态性 类设计之…

git log 进入命令行后 退出的几种方法

git log 是git 中很有用的命令,会列出git的最近的操作内容,并且用 冒号来作为提示行。在 Git 命令行中,如果你看到 :,通常是因为你进入了一个查看器界面,比如 git log 或 git diff。要退出这个界面,你可以按下 q 键。以下是一些常见的退出方法: 退出查看器界面: 按 q 键…

OpenAI的GPT-4o:普通人的AI秘书来了

1. 惊艳时刻:AI比你想象的更"人性" 早餐时,张三正埋头刷推送,一篇关于OpenAI发布GPT-4o的文章瞬间点燃了他的好奇心。这个AI简直是科技圈的惊雷!竟然可以像真人一样说话、理解语境、实时交互,甚至能读懂你的情绪。这哪里还是以前那个机械的聊天机器人,简直就是…

搭建Node.js环境

Node.js安装配置详细教程 1.安装前检查自己电脑上是否安装node.js (1)打开终端:Win + R (2)输入node -v来检查是否安装node(3)显示’node’不是内部或外部命令,说明未安装node 2.官网下载3.双击安装:这里不要勾选,然后安装即可 4.验证node.js是否安装成功 (1)终端环…