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的更多相关文章

  1. [板子]最小费用最大流(Dijkstra增广)

    最小费用最大流板子,没有压行.利用重标号让边权非负,用Dijkstra进行增广,在理论和实际上都比SPFA增广快得多.教程略去.转载请随意. #include <cstdio> #incl ...

  2. [板子]ISAP

    ISAP求最大流,敲了一发板子,无压行,教程略去.转载请随意. #include <cstdio> #include <cstring> #include <algori ...

  3. [板子]倍增LCA

    倍增LCA板子,没有压行,可读性应该还可以.转载请随意. #include <cstdio> #include <cstring> #include <algorithm ...

  4. UP Board 人若有大胆,板子就很惨:首次上电开机失败

    前言 原创文章,转载引用务必注明链接. 注意:拍照自带抖动功能,画质大家凑合着看.冬日天气干燥,手触摸板子前建议流水洗手或者握持大体积导电体将静电放走. 本文使用Markdown写成,为获得更好的阅读 ...

  5. orpsocv2 从ROM(bootrom)启动分析--以atlys板子的启动为例子

    1 复位后的启动地址 1) 复位后,启动地址在or1200_defines.v最后宏定义,atlys板子的目录:orpsocv2\boards\xilinx\atlys\rtl\verilog\inc ...

  6. Lattice FPGA 板子 调试笔记

    最近在调试LATTICE  FPGA 做的视频板子,颇不顺利,所以记录下来作为以后的参考: 1.FPGA的IO口不是所有的都是双向的,有些有特殊作用的是单向的. 在查阅 LatticeECP3-17E ...

  7. 【图像处理】【SEED-VPM】1.板子基本操作流程

    >>>>>>>>>>>>>>>>>>>>>>>>> ...

  8. NFS 网络文件系统挂载在A8板子上

    我承认自己是菜鸟,没什么网络知识就来搞挂载nfs网络文件系统,花费了5天的时间才把nfs网络文件系统成功挂载在A8板子上,实现了A8板子和虚拟机的文件共享.分享一下个人经验: 以下是基于nfs已经完成 ...

  9. [PCB设计] 2、畸形PCB板子的制作核心——AD14导入dwg格式文件的方法

    本文参考园友:The Zone of up.Craftor http://www.cnblogs.com/craftor/archive/2012/06/28/2567259.html 硬件工程师在做 ...

随机推荐

  1. 【轉】JS,Jquery获取各种屏幕的宽度和高度

    Javascript: 网页可见区域宽: document.body.clientWidth网页可见区域高: document.body.clientHeight网页可见区域宽: document.b ...

  2. 凸包GiftWrapping GrahamScan 算法实现

    开始 游戏内有需求做多边形碰撞功能,但是接入box2d相对游戏的需求来说太重度了.所以准备自己实现碰撞. 确定多边形,必然要用到凸包的算法.在github上也找到了一些lua实现,但是这里的算法没有考 ...

  3. GCD之线程挂起与恢复

    我们可以使用dispatch_suspend函数暂停一个queue以阻止它执行block对象;使用dispatch_resume函数继续dispatch queue.调用dispatch_suspen ...

  4. 高德地图JSApi

    <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type" content ...

  5. es6箭头函数讲解

    es6箭头函数的用法 箭头函数是es6的一种函数的简写方法. 如下: var f = v = > v; //等同于 var f = function(v){ return v; } var su ...

  6. Problem 2144 Shooting Game fzu

    Problem 2144 Shooting Game Accept: 99    Submit: 465Time Limit: 1000 mSec    Memory Limit : 32768 KB ...

  7. Ionic3学习笔记(二)主题化

    本文为原创文章,转载请标明出处 目录 CSS实用属性 文本相关 位置相关 padding & margin 自定义颜色 平台样式 覆写Ionic Sass变量 RTL支持 1. CSS实用属性 ...

  8. Elixir游戏服设计五

    在<Elixir游戏服设计一>里提到,按照系统功能划分成app要保证原子性很难, 现在想想也没那么难.保证原子性,无非就是需要某个单点去完成操作.那么选择玩家进程去做原子性工作就可以了. ...

  9. C#.net干货,最全公共帮助类

    比较全面的c#帮助类,日常工作收集,包括前面几家公司用到的,各式各样的几乎都能找到,所有功能性代码都是独立的类,类与类之间没有联系,可以单独引用至项目,分享出来,方便大家,几乎都有注释,喜欢的请点赞, ...

  10. jq 通过标签属性匹配标签

    有时候会有这样的需求 在一堆的标签中定位到某个标签去获取值 这时候我们就可以通过使用自定义属性将这一堆标签打上不同的标记 通过属性定位标签了 下面是代码: <input class=" ...