[板子]segTree
segTree
参考:http://www.cnblogs.com/TenosDoIt/p/3453089.html#c
初学者建议先参考上面“一步一步理解线段树”学习理论。
在这里Code分别为区间求和&区间求积的做法。
分别对应OJ luogu的3372和3373
1.区间和
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
long long val,lazytag;
}segTree[*+];
];
int n,m,t,x,y,k;
void build(int root,long long arr[],int istart,int iend){//建树
segTree[root].lazytag=;
if(istart==iend){
segTree[root].val=arr[istart];
}else{
;
build(root*,arr,istart,mid);
build(root*+,arr,mid+,iend);
segTree[root].val=segTree[root*].val+segTree[root*+].val;
}
}
void pushDown(int root,int start,int end){//插入懒标记
){
segTree[root*].lazytag+=segTree[root].lazytag;
segTree[root*+].lazytag+=segTree[root].lazytag;
;
segTree[root*].val+=segTree[root].lazytag*(mid-start+);
segTree[root*+].val+=segTree[root].lazytag*(end-mid);
segTree[root].lazytag=;
}
}
long long query(int root,int nstart,int nend,int qstart,int qend){//查询区间
if(qstart>nend||qend<nstart){
;
}if(qstart<=nstart&&qend>=nend){
return segTree[root].val;
}
pushDown(root,nstart,nend);
;
,nstart,mid,qstart,qend)+query(root*+,mid+,nend,qstart,qend);
}
void update(int root,int nstart,int nend,int ustart,int uend,int addval){//赋值
if(ustart>nend||uend<nstart){
return;
}if(ustart<=nstart&&uend>=nend){
segTree[root].lazytag+=addval;
segTree[root].val+=addval*(nend-nstart+);
return;
}
pushDown(root,nstart,nend);
;
update(root*,nstart,mid,ustart,uend,addval);
update(root*+,mid+,nend,ustart,uend,addval);
segTree[root].val=segTree[root*].val+segTree[root*+].val;
}
int main(){
scanf("%lld%lld",&n,&m);
;i<=n;i++){
scanf("%lld",&a[i]);
}
build(,a,,n);
;i<=m;i++){
scanf("%lld",&t);
){
scanf("%lld%lld%lld",&x,&y,&k);
update(,,n,x,y,k);
}){
scanf("%lld%lld",&x,&y);
printf(,,n,x,y));
}
}
}
2.区间积
在这里要点几个点注意:
1:tag2的初始值为1;
2:pushdown里先tag2后tag1(先乘后加);
3:对tag2进行push需要先把tag1*tag2,tag2*tag2,val*tag2,最后别忘了tag2=1;
4:tag2不需要乘区间,原因是:a*(b+c)=a*b+a*c,乘法分配律;
#include<cstdio>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
struct node{
long long val,lazytag,lazytag2;
}segTree[*+];
];
long long n,m,t,x,y,k,p;
void build(int root,long long arr[],int istart,int iend){//建树
segTree[root].lazytag=;
segTree[root].lazytag2=;
if(istart==iend){
segTree[root].val=arr[istart];
}else{
;
build(root*,arr,istart,mid);
build(root*+,arr,mid+,iend);
segTree[root].val=segTree[root*].val+segTree[root*+].val;
}
}
void pushDown(int root,int start,int end){//插入懒标记
**){**
segTree[root*].lazytag=(segTree[root*].lazytag*segTree[root].lazytag2)%p;
segTree[root*+].lazytag=(segTree[root*+].lazytag*segTree[root].lazytag2)%p;
segTree[root*].lazytag2=(segTree[root*].lazytag2*segTree[root].lazytag2)%p;
segTree[root*+].lazytag2=(segTree[root*+].lazytag2*segTree[root].lazytag2)%p;
;
segTree[root*].val=(segTree[root*].val*(segTree[root].lazytag2))%p;
segTree[root*+].val=(segTree[root*+].val*(segTree[root].lazytag2))%p;
segTree[root].lazytag2=;
}
){
segTree[root*].lazytag+=segTree[root].lazytag;
segTree[root*+].lazytag+=segTree[root].lazytag;
;
segTree[root*].val+=segTree[root].lazytag*(mid-start+);
segTree[root*+].val+=segTree[root].lazytag*(end-mid);
segTree[root].lazytag=;
}
}
long long query(int root,int nstart,int nend,int qstart,int qend){//查询区间
if(qstart>nend||qend<nstart){
;
}if(qstart<=nstart&&qend>=nend){
return segTree[root].val;
}
pushDown(root,nstart,nend);
;
,nstart,mid,qstart,qend)+query(root*+,mid+,nend,qstart,qend);
}
void update(int root,int nstart,int nend,int ustart,int uend,int addval){//赋值
if(ustart>nend||uend<nstart){
return;
}if(ustart<=nstart&&uend>=nend){
segTree[root].lazytag+=addval;
segTree[root].val+=addval*(nend-nstart+);
return;
}
pushDown(root,nstart,nend);
;
update(root*,nstart,mid,ustart,uend,addval);
update(root*+,mid+,nend,ustart,uend,addval);
segTree[root].val=segTree[root*].val+segTree[root*+].val;
}
**void tupdate(int root,int nstart,int nend,int ustart,int uend,int addval){//赋值(chengfa**
if(ustart>nend||uend<nstart){
return;
}if(ustart<=nstart&&uend>=nend){
segTree[root].lazytag=(segTree[root].lazytag*addval)%p;
segTree[root].lazytag2=(segTree[root].lazytag2*addval)%p;
segTree[root].val=(segTree[root].val*addval)%p;
return;
}
pushDown(root,nstart,nend);
;
tupdate(root*,nstart,mid,ustart,uend,addval);
tupdate(root*+,mid+,nend,ustart,uend,addval);
segTree[root].val=segTree[root*].val+segTree[root*+].val;
}
int main(){
scanf("%lld%lld%lld",&n,&m,&p);
;i<=n;i++){
scanf("%lld",&a[i]);
}
build(,a,,n);
;i<=m;i++){
scanf("%lld",&t);
){
scanf("%lld%lld%lld",&x,&y,&k);
update(,,n,x,y,k);
}){
scanf("%lld%lld",&x,&y);
printf(,,n,x,y)%p);
}){
scanf("%lld%lld%lld",&x,&y,&k);
tupdate(,,n,x,y,k);
}
}
;
}
并且感谢will7101的帮助
[板子]segTree的更多相关文章
- [板子]最小费用最大流(Dijkstra增广)
最小费用最大流板子,没有压行.利用重标号让边权非负,用Dijkstra进行增广,在理论和实际上都比SPFA增广快得多.教程略去.转载请随意. #include <cstdio> #incl ...
- [板子]ISAP
ISAP求最大流,敲了一发板子,无压行,教程略去.转载请随意. #include <cstdio> #include <cstring> #include <algori ...
- [板子]倍增LCA
倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...
- UP Board 人若有大胆,板子就很惨:首次上电开机失败
前言 原创文章,转载引用务必注明链接. 注意:拍照自带抖动功能,画质大家凑合着看.冬日天气干燥,手触摸板子前建议流水洗手或者握持大体积导电体将静电放走. 本文使用Markdown写成,为获得更好的阅读 ...
- orpsocv2 从ROM(bootrom)启动分析--以atlys板子的启动为例子
1 复位后的启动地址 1) 复位后,启动地址在or1200_defines.v最后宏定义,atlys板子的目录:orpsocv2\boards\xilinx\atlys\rtl\verilog\inc ...
- Lattice FPGA 板子 调试笔记
最近在调试LATTICE FPGA 做的视频板子,颇不顺利,所以记录下来作为以后的参考: 1.FPGA的IO口不是所有的都是双向的,有些有特殊作用的是单向的. 在查阅 LatticeECP3-17E ...
- 【图像处理】【SEED-VPM】1.板子基本操作流程
>>>>>>>>>>>>>>>>>>>>>>>>> ...
- NFS 网络文件系统挂载在A8板子上
我承认自己是菜鸟,没什么网络知识就来搞挂载nfs网络文件系统,花费了5天的时间才把nfs网络文件系统成功挂载在A8板子上,实现了A8板子和虚拟机的文件共享.分享一下个人经验: 以下是基于nfs已经完成 ...
- [PCB设计] 2、畸形PCB板子的制作核心——AD14导入dwg格式文件的方法
本文参考园友:The Zone of up.Craftor http://www.cnblogs.com/craftor/archive/2012/06/28/2567259.html 硬件工程师在做 ...
随机推荐
- SpringBoot文档翻译系列——29.SQL数据源
原创作品,可以转载,但是请标注出处地址: 因为需要使用到这方面内容,所有对这一部分进行了翻译. 29 使用SQL数据源 SpringBoot为SQL数据源提供了广泛支持,从直接使用JdbcTempl ...
- mysql操作sql的小技巧
本篇集中整理一下执行sql的小技巧,这种方式不仅带来了操作上的便捷,也可以保证数据可以数据的安全性. 1:查询数据(保证查询性能) 首先想先解释一下 SELECT * 和 SELECT t.id , ...
- UWP brush
---some words---- 1.Alpha:透明度 2.Argb :Alpha red green blue 3.brush: [brʌʃ] 刷子,笔画,笔刷 4.fore 前头 5.F ...
- nodejs+express+mongoose无法获取数据库数据问题解决
通过mongoose与mongodb进行操作.而mongoose是通过model来创建mongodb中对应的collection的,这样你通过如下的代码: mongoose.model('User', ...
- ch7-列表渲染(v-for key 数组更新检测 显示过滤/排序结果)
1 说明 我们用 v-for 指令根据一组数组的选项列表进行渲染. v-for 指令需要以 item in items 形式的特殊语法, items 是源数据数组并且 item 是数组元素迭代的别名. ...
- ASP.NET没有魔法——ASP.NET MVC 与数据库大集合
ASP.NET没有魔法——ASP.NET与数据库 ASP.NET没有魔法——ASP.NET MVC 与数据库之MySQL ASP.NET没有魔法——ASP.NET MVC 与数据库之ORM ASP.N ...
- jquery系列教程1-选择器全解
全栈工程师开发手册 (作者:栾鹏) 快捷链接: jquery系列教程1-选择器全解 jquery系列教程2-style样式操作全解 jquery系列教程3-DOM操作全解 jquery系列教程4-事件 ...
- HTTP错误代码大全
HTTP出错大全 101 - Switching Protocols Top Success Codes 200 - OK201 - Created202 - Accepted203 - Non-Au ...
- java中==与equel的区别
值类型是存储在内存中的堆栈(以后简称栈),而引用类型的变量在栈中仅仅是存储引用类型变量的地址,而其本身则存储在堆中. ==操作比较的是两个变量的值是否相等,对于引用型变量表示的是两个变量在堆中存储的地 ...
- Spring 源码剖析IOC容器(一)概览
目录 一.容器概述 二.核心类源码解读 三.模拟容器获取Bean ======================= 一.容器概述 spring IOC控制反转,又称为DI依赖注入:大体是先初始化bean ...