代码源 线段树模板

线段树1

 

思路:

我们需要维护的东西是序列的最小值和最小值个数

这道题没有修改操作,因此不考虑修改

然后考虑Pushup

最小值很简单,直接取min

最小值个数怎么维护呢?考虑这个区间需要维护的值如何从左右两个区间获得

如果左右两个子区间的最小值相同,那么就可以直接相加

否则,如果这个区间的最小值是左区间最小值,直接赋值左区间的

否则就是右区间的

学一学dls的代码风格,感觉很高级QwQ

Code:

#include <bits/stdc++.h>#define int long longusing namespace std;const int mxn=2e5+10;
const int mxe=2e5+10;struct info{int minv,mincnt;
};info operator+(const info &l,const info &r){info a;a.minv=min(l.minv,r.minv);if(l.minv==r.minv) a.mincnt=l.mincnt+r.mincnt;else if(l.minv<r.minv) a.mincnt=l.mincnt;else a.mincnt=r.mincnt;return a;
}struct ty{info val;
}tree[mxe<<2];int n,Q,x,d,l,r,op;
int a[mxn]; void pushup(int rt){tree[rt].val=tree[rt<<1].val+tree[rt<<1|1].val;
}
void build(int rt,int l,int r){if(l==r){tree[rt].val={a[l],1};return;}int mid=l+r>>1;build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);pushup(rt);
}
info query(int rt,int l,int r,int x,int y){if(x<=l&&r<=y){return tree[rt].val;}int mid=l+r>>1;if(y<=mid) return query(rt<<1,l,mid,x,y);else if(x>mid) return query(rt<<1|1,mid+1,r,x,y);else{return query(rt<<1,l,mid,x,y)+query(rt<<1|1,mid+1,r,x,y);}
}
void change(int rt,int l,int r,int x,int k){if(l==r){tree[rt].val={k,1};return;}int mid=l+r>>1;if(x<=mid) change(rt<<1,l,mid,x,k);else change(rt<<1|1,mid+1,r,x,k);pushup(rt);
}
void solve(){cin>>n>>Q;for(int i=1;i<=n;i++) cin>>a[i];build(1,1,n);while(Q--){cin>>op;if(op==1){cin>>x>>d;change(1,1,n,x,d);}else{cin>>l>>r;cout<<query(1,1,n,l,r).minv<<" "<<query(1,1,n,l,r).mincnt<<'\n';}}
}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int __=1;//cin>>__;while(__--)solve();return 0;
}

线段树2

题意:

 

思路:

我们需要维护一个区间的最大子段和

两个子区间的最大子段和怎么得到一整个区间的最大子段和呢

分类讨论即可

这个子段可能完全出现在左区间,也可能完全出现在右区间,也可能是左区间的右部分+右区间的左部分

前两种情况直接赋值即可

对于第三种情况,其实就是左区间的右部分最大子段和+右区间的左部分的最大子段和 之和

因此我们需要维护这两个值

然后开始考虑怎么维护

对于左部分最大子段和,它可能是左区间的左部分最大子段和,也有可能是左区间一整个区间+右区间的左部分最大子段和

右部分最大子段和同理

最后来看dls的板子,它需要写构造函数,因为我们这次在build的时候没有把所有的值都初始化

Code:

#include <bits/stdc++.h>#define int long longusing namespace std;const int mxn=2e5+10;
const int mxe=2e5+10;struct info{int mss,mpre,msuf,s;info(){}info(int a) :mss(a),mpre(a),msuf(a),s(a){}
};info operator+(const info &l,const info &r){info a;a.s=l.s+r.s;a.mss=max(max(l.mss,r.mss),l.msuf+r.mpre);a.mpre=max(l.mpre,l.s+r.mpre);a.msuf=max(r.msuf,r.s+l.msuf);return a;
}struct ty{info val;
}tree[mxe<<2];int n,Q,x,d,l,r,op;
int a[mxn]; void pushup(int rt){tree[rt].val=tree[rt<<1].val+tree[rt<<1|1].val;
}
void build(int rt,int l,int r){if(l==r){tree[rt].val=info(a[l]);return;}int mid=l+r>>1;build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);pushup(rt);
}
info query(int rt,int l,int r,int x,int y){if(x<=l&&r<=y){return tree[rt].val;}int mid=l+r>>1;if(y<=mid) return query(rt<<1,l,mid,x,y);else if(x>mid) return query(rt<<1|1,mid+1,r,x,y);else{return query(rt<<1,l,mid,x,y)+query(rt<<1|1,mid+1,r,x,y);}
}
void change(int rt,int l,int r,int x,int k){if(l==r){tree[rt].val=info(k);return;}int mid=l+r>>1;if(x<=mid) change(rt<<1,l,mid,x,k);else change(rt<<1|1,mid+1,r,x,k);pushup(rt);
}
void solve(){cin>>n>>Q;for(int i=1;i<=n;i++) cin>>a[i];build(1,1,n);while(Q--){cin>>op;if(op==1){cin>>x>>d;change(1,1,n,x,d);}else{cin>>l>>r;cout<<query(1,1,n,l,r).mss<<'\n';}}
}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int __=1;//cin>>__;while(__--)solve();return 0;
}

线段树打标记

题意:

思路:

我们需要维护的是最大值,这个很好维护,Pushup直接取max即可

问题是需要区间修改,区间加

这个加个add标记即可,在Pushdown的时候更新mx属性

这种打标记的最重要的是如何在Pushdown的时候观察区间修改操作如何影响需要维护的值 

在这里很简单,直接最大值mx使加上add即可

Code:

#include <bits/stdc++.h>#define int long longusing namespace std;const int mxn=2e5+10;
const int mxe=2e5+10;struct Segtree{int mx,add;
}tree[mxe<<2];int n,Q,x,d,l,r,op;
int a[mxn]; void settag(int rt,int t){tree[rt].add+=t;tree[rt].mx+=t;
}
void pushup(int rt){tree[rt].mx=max(tree[rt<<1].mx,tree[rt<<1|1].mx);
}
void pushdown(int rt){if(tree[rt].add){settag(rt<<1,tree[rt].add);settag(rt<<1|1,tree[rt].add);tree[rt].add=0;}
}
void build(int rt,int l,int r){if(l==r){tree[rt]={a[l],0};return;}int mid=l+r>>1;build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);pushup(rt);
}
int query(int rt,int l,int r,int ql,int qr){if(ql<=l&&r<=qr){return tree[rt].mx;}pushdown(rt);int mid=l+r>>1;if(qr<=mid) return query(rt<<1,l,mid,ql,qr);else if(ql>mid) return query(rt<<1|1,mid+1,r,ql,qr);else{return max(query(rt<<1,l,mid,ql,qr),query(rt<<1|1,mid+1,r,ql,qr));}
}
void modify(int rt,int l,int r,int ql,int qr,int d){if(ql<=l&&r<=qr){settag(rt,d);return;}pushdown(rt);int mid=l+r>>1;if(qr<=mid) modify(rt<<1,l,mid,ql,qr,d);else if(ql>mid) modify(rt<<1|1,mid+1,r,ql,qr,d);else{modify(rt<<1,l,mid,ql,qr,d);modify(rt<<1|1,mid+1,r,ql,qr,d);}pushup(rt);
}
void solve(){cin>>n>>Q;for(int i=1;i<=n;i++) cin>>a[i];build(1,1,n);while(Q--){cin>>op;if(op==1){cin>>l>>r>>d;modify(1,1,n,l,r,d);}else{cin>>l>>r;cout<<query(1,1,n,l,r)<<'\n';}}
}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int __=1;//cin>>__;while(__--)solve();return 0;
}

线段树打标记2

题意:

 Code:

#include <bits/stdc++.h>#define int long longusing namespace std;const int mxn=2e5+10;
const int mxe=2e5+10;
const int mod=1e9+7;struct tag{int mul,add;
};tag operator+(const tag &l,const tag &r){return {(l.mul*r.mul)%mod,(l.add*r.mul+r.add)%mod};
}
struct Segtree{tag t;int val;int sz;
}tree[mxe<<2];int n,Q,x,d,l,r,op;
int a[mxn]; void settag(int rt,tag t){tree[rt].t=tree[rt].t+t;tree[rt].val=(tree[rt].val*t.mul+tree[rt].sz*t.add)%mod;
}
void pushup(int rt){tree[rt].val=(tree[rt<<1].val+tree[rt<<1|1].val)%mod;
}
void pushdown(int rt){if(tree[rt].t.mul!=1||tree[rt].t.add!=0){settag(rt<<1,tree[rt].t);settag(rt<<1|1,tree[rt].t);tree[rt].t={1,0};}
}
void build(int rt,int l,int r){tree[rt].t={1,0};tree[rt].sz=r-l+1;if(l==r){tree[rt].val=a[l];return;}int mid=l+r>>1;build(rt<<1,l,mid);build(rt<<1|1,mid+1,r);pushup(rt);
}
int query(int rt,int l,int r,int ql,int qr){if(ql<=l&&r<=qr){return tree[rt].val;}pushdown(rt);int mid=l+r>>1;if(qr<=mid) return query(rt<<1,l,mid,ql,qr);if(ql>mid) return query(rt<<1|1,mid+1,r,ql,qr);return (query(rt<<1,l,mid,ql,qr)+query(rt<<1|1,mid+1,r,ql,qr))%mod;
}
void modify(int rt,int l,int r,int ql,int qr,tag t){if(ql==l&&r==qr){settag(rt,t);return;}pushdown(rt);int mid=l+r>>1;if(qr<=mid) modify(rt<<1,l,mid,ql,qr,t);else if(ql>mid) modify(rt<<1|1,mid+1,r,ql,qr,t);else{modify(rt<<1,l,mid,ql,mid,t);modify(rt<<1|1,mid+1,r,mid+1,qr,t);}pushup(rt);
}
void solve(){cin>>n>>Q;for(int i=1;i<=n;i++) cin>>a[i];build(1,1,n);while(Q--){cin>>op;if(op==1){cin>>l>>r>>d;modify(1,1,n,l,r,(tag){1,d});}else if(op==2){cin>>l>>r>>d;modify(1,1,n,l,r,(tag){d,0});}else if(op==3){cin>>l>>r>>d;modify(1,1,n,l,r,(tag){0,d});}else{cin>>l>>r;cout<<query(1,1,n,l,r)<<'\n';}}
}
signed main(){ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);int __=1;//cin>>__;while(__--)solve();return 0;
}

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

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

相关文章

Scrpay框架之MongoDB--Index

目录 MongoDB-Index 概念 索引类型 创建索引 注意 样例 索引的查看 删除索引 语法 样例 检测索引的速度优势 Mongo-Unique Index And Compound Index 唯一索引&#xff08;Unique Index&#xff09; 添加唯一索引的语法 利用唯一索引进行数据去重 复合索引&a…

springboot增加logback日志记录ip

1、增加logback配置文件&#xff1a; public class IPLogConfig extends ClassicConverter {Overridepublic String convert(ILoggingEvent event) {RequestAttributes requestAttributes RequestContextHolder.getRequestAttributes();if (requestAttributes null) {return…

HTTP协议、存储、Ajax

HTTP协议、存储、Ajax 前端数据交互与HTTP协议 前后端通信 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><title>初识前后端通信</title></head><body><script>// 1.前后端通信…

SpringCloud-Nacos配置管理

文章目录 Nacos配置管理统一配置管理在nacos中添加配置文件从微服务拉取配置 配置热更新方式一方式二 配置共享1&#xff09;添加一个环境共享配置2&#xff09;在user-service中读取共享配置3&#xff09;运行两个UserApplication&#xff0c;使用不同的profile3&#xff09;运…

PHP函数、数组和错误处理:简单实用的开发技巧和错误处理方法

目录 PHP函数 函数的基本概念&#xff1a; 函数定义语法&#xff1a; 函数命名关系&#xff1a; 参数详解 形参 实参 ​编辑 默认值 引用传递 函数体 函数返回值 作用域 静态变量 可变函数 匿名函数 基本概念 闭包 伪类型 库函数 有关输出的函数 有关时间…

CentOS7 静默方式安装 Oracle19C

CentOS7 静默方式安装 Oracle19C 操作系统&#xff1a;CentOS7 Oracle&#xff1a; 19C 安装常用工具和依赖 yum -y install vim tar net-tools wget perl python3 readline* deltarpm python-deltarpm \zip unzip bc compat-libcap1* compat-libcap* binutils compat-libstdc…

记一次docker-compose的坎坷安装经历

最近公司在做一个kafka项目&#xff0c;所以想用docker来安装kafka集群&#xff0c;所以安装完docker后就准备安装docker-compose&#xff0c;但在安装过程中确碰到了各种问题&#xff0c;搞了两个半天再通过翻墙工具才终于搞定。 首先看了篇文章显示安装前要对应docker版本。 …

【Kafka面试题1】Kafka消费者是pull(拉)还是push(推)模式,这种模式有什么好处?

Kafka消费者是pull(拉)还是push(推)模式&#xff0c;这种模式有什么好处&#xff1f; 一、概述回答 Kafka中的Producer和consumer采用的是push-and-pull模式&#xff0c;即Producer只管向broker push消息&#xff0c;consumer只管从broker pull消息&#xff0c;两者对消息的生…

【UE5 Cesium】06-Cesium for Unreal 从一个地点飞行到另一个地点(上)

UE版本&#xff1a;5.1 介绍 本文以在墨尔本和悉尼这两个城市间为例&#xff0c;介绍如何使用虚幻5引擎和Cesium for Unreal插件在这两个城市间进行飞行移动&#xff0c;其中墨尔本和悉尼城市的倾斜摄影是Cesium官方仓库中自带的资产&#xff0c;我们引入到自己的Cesium账号…

【⑦MySQL】· 一文了解四大子查询

前言 ✨欢迎来到小K的MySQL专栏&#xff0c;本节将为大家带来MySQL标量/单行子查询、列子/表子查询的讲解✨ 目录 前言一、子查询概念二、标量/单行子查询、列子/表子查询三、总结 一、子查询概念 子查询指一个查询语句嵌套在另一个查询语句内部的查询&#xff0c;这个特性从My…

8.用python写网路爬虫,Scrapy

前言 Scrapy 是一个流行的网络爬虫框架&#xff0c;它拥有很多简化网站抓取的高级函数。本章中&#xff0c;我们将学习使用 Scrapy 抓取示例网站&#xff0c;目标任务与第2章相同。然后&#xff0c;我们还会介绍 Portia &#xff0c;这是一个基于 Scrapy 的应用&#xff0c;允许…

MATLAB 之 低层绘图操作和光照及材质处理

这里写目录标题 一、低层绘图操作1. 曲线对象2. 曲面对象3. 文本对象4. 其他核心对象4.1 区域块对象4.2 方框对象 二、光照和材质处理1. 光照处理2. 材质处理2.1 图形对象的反射特性2.2 material 函数 一、低层绘图操作 MATLAB 将曲线、曲面、文本等图形均视为对象&#xff0c…