首页 > 其他分享 >P3373 【模板】线段树 2

P3373 【模板】线段树 2

时间:2024-01-14 13:33:06浏览次数:21  
标签:node ll end 线段 start lazymul lazyadd P3373 模板

原题链接

code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
ll a[100005]={0};
ll lazyadd[400005]={0};
ll lazymul[400005]={0};
ll tree[400005]={0};
ll n,q,m;

void build(ll node, ll start, ll end)
{
    lazyadd[node]=0;
    lazymul[node]=1;

    if(start!=end)
    {
        ll mid=(start+end)/2;
        build(node*2,start,mid);
        build(node*2+1,mid+1,end);
        tree[node]=(tree[2*node+1]+tree[2*node])%m;
    }
    else tree[node]=a[start]%m;
}

void updatemul(ll node, ll start, ll end, ll l, ll r, ll val)
{
    if(lazyadd[node]!=0||lazymul[node]!=1)//lazy代表当前节点要加或乘的数量
    {
        tree[node]=(lazymul[node]*tree[node]%m+(end-start+1)*lazyadd[node]%m)%m;//每更新一个mul都会更新一次add所以add已经被后来的mul乘过了,可以直接加
        if(start!=end)
        {
            lazymul[node*2]=lazymul[node*2]*lazymul[node]%m;//每一个mul都是新的,不会出现 重复的情况
            lazyadd[node*2]=(lazyadd[node*2]*lazymul[node]+lazyadd[node])%m;//每传递一个mul都要给被传递节点的现在值tree和待加值add乘上
            lazymul[node*2+1]=lazymul[node*2+1]*lazymul[node]%m;
            lazyadd[node*2+1]=(lazyadd[node*2+1]*lazymul[node]+lazyadd[node])%m;
        }
        lazymul[node]=1;
        lazyadd[node]=0;
    }
    if(r<start||l>end) return;

    if(start>=l&&end<=r)//如果是最外面的完全包裹区间
    {
        tree[node]=tree[node]*val%m;
        if(start!=end)
        {
            lazyadd[node*2]=lazyadd[node*2]*val%m;
            lazymul[node*2]=lazymul[node*2]*val%m;
            lazyadd[node*2+1]=lazyadd[node*2+1]*val%m;
            lazymul[node*2+1]=lazymul[node*2+1]*val%m;
        }
        return;
    }

    ll mid=(start+end)/2;
    updatemul(node*2,start,mid,l,r,val);
    updatemul(node*2+1,mid+1,end,l,r,val);
    tree[node]=(tree[node*2]+tree[node*2+1])%m;//这个区间的值并不是全部修改
}

void updateadd(ll node, ll start, ll end, ll l, ll r, ll val)
{
    if(lazyadd[node]!=0||lazymul[node]!=1)
    {
        tree[node]=(lazymul[node]*tree[node]%m+(end-start+1)*lazyadd[node]%m)%m;
        if(start!=end)
        {
            lazymul[node*2]=lazymul[node*2]*lazymul[node]%m;
            lazyadd[node*2]=(lazyadd[node*2]*lazymul[node]+lazyadd[node])%m;
            lazymul[node*2+1]=lazymul[node*2+1]*lazymul[node]%m;
            lazyadd[node*2+1]=(lazyadd[node*2+1]*lazymul[node]+lazyadd[node])%m;
        }
        lazymul[node]=1;
        lazyadd[node]=0;
    }
    if(r<start||l>end) return;

    if(start>=l&&end<=r)
    {
        tree[node]=(tree[node]+val*(end-start+1))%m;
        if(start!=end)
        {
            lazyadd[node*2]+=val;
            lazyadd[node*2+1]+=val;
        }
        return;
    }

    ll mid=(start+end)/2;
    updateadd(node*2,start,mid,l,r,val);
    updateadd(node*2+1,mid+1,end,l,r,val);
    tree[node]=(tree[node*2]+tree[node*2+1])%m;
}

ll query(ll node, ll start, ll end, ll l, ll r)
{
    if(r<start||l>end) return 0;
    if(lazyadd[node]!=0||lazymul[node]!=1)
    {
        tree[node]=(lazymul[node]*tree[node]%m+(end-start+1)*lazyadd[node]%m)%m;
        if(start!=end)
        {
            lazymul[node*2]=lazymul[node*2]*lazymul[node]%m;
            lazyadd[node*2]=(lazyadd[node*2]*lazymul[node]+lazyadd[node])%m;
            lazymul[node*2+1]=lazymul[node*2+1]*lazymul[node]%m;
            lazyadd[node*2+1]=(lazyadd[node*2+1]*lazymul[node]+lazyadd[node])%m;
        }
        lazymul[node]=1;
        lazyadd[node]=0;
    }

    if(start>=l&&end<=r) return tree[node]%m;
    else
    {
        ll mid=(start+end)/2;
        return (query(node*2,start,mid,l,r)+query(node*2+1,mid+1,end,l,r))%m;
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> q >> m;
    for(ll i=1; i<=n; i++) cin >> a[i];
    build(1,1,n);
    while(q--)
    {
        ll op,x,y,k;
        cin >> op;
        if(op==1)
        {
            cin >> x >> y >> k;
            updatemul(1,1,n,x,y,k);
        }
        else if(op==2)
        {
            cin >> x >> y >> k;
            updateadd(1,1,n,x,y,k);
        }
        else
        {
            cin >> x >> y;
            cout << query(1,1,n,x,y) << endl;
        }
    }
    return 0;
}

标签:node,ll,end,线段,start,lazymul,lazyadd,P3373,模板
From: https://www.cnblogs.com/pure4knowledge/p/17963611

相关文章

  • Aspose.Words使用word模板中的书签/域插入信息并导出
    首先我大概叙述一下我对这个东西的理解毕竟我也只是记录一下,确保下次自己在看的时候可以看懂,所以写的比较详细且傻瓜首先这个word文档不是凭空生成的,是你事先就把文档创建好的,里边的内容,格式都是实现创建好的只留下一些需要插入数据的地方,当然这些需要插入数据的地方也不是空着的......
  • Helm概述,安装,部署,chart模板使用
    Helm概述Helm是一个用于管理Kubernetes应用程序的工具,它提供了一个简单而有效的方式来定义、安装和部署应用程序。Helm通过使用可重复使用的模板(称为Charts)来描述应用程序的Kubernetes资源,并提供了一个命令行界面来管理这些Charts。Helm的核心概念包括:Chart:Chart是Helm的基本单元,它......
  • 一套模板搞定二叉树算法题--二叉树算法讲解002
    1、二叉树的递归递归:2、二叉树遍历之DFS深度优先遍历2.1、遍历的概念每个节点都要恰好被访问一次,本质上是二叉树的线性化。一个树形的结构,线性化为一个数组之类的"串"的结构。2.2、DFS深度优先遍历示例二叉树原型图:2.2.1、前序遍历前序遍历执行顺序:根节点--对左子......
  • 类模板实现简单的数组
    //Myarray.hpp#pragmaoncetemplate<classT>classMyArray{public: MyArray(intcapacity){ this->mCapacity=capacity; this->msize=0; this->p=newT[this->mCapacity]; } //copy MyArray(constMyArray&arr){ this->......
  • 类模板和友元
    友元内部实现#include<iostream>#include<stdio.h>#include<stdlib.h>#include<algorithm>#include<numeric>template<classNameType,classAgeType>classMark{ friendvoidprintMaker(Mark<NameType,AgeType>&p)......
  • 线段树练习
    Ⅰ.差分与前缀和P2184贪婪大陆题意:给定防线长度\(n\)和操作次数\(m\),每次在[\(l\),\(r\)]内布下一种雷,查询区间雷的种类数。分析:用线段的方式表示区间布的雷:如[2,4]内的种类=[1,4]内的起点-[1,2]内的终点P1438无聊的数列题意:区间加等差......
  • Jenkins邮件模板
    模板一:1<!DOCTYPEhtml>2<html>3<head>4<metacharset="UTF-8">5<title>${ENV,var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title>6</head>78<bodyleftmargin="8"marginw......
  • 【opencv学习笔记】028之模板匹配——matchTemplate函数详解
    目录​ ​一、前言​​​ ​二、模板匹配​​​ ​1、模板匹配是个啥​​​ ​2、常用匹配算法​​​​ ​3、API​​​ ​4、代码展示​​​ ​5、执行结果​​一、前言遭遇了点突发情况,所以今天更新的有点晚,也不知道能不能等到今天发出去了。终于可以从模板匹......
  • Microsoft 365 新功能速递:通信合规性–检测Copilot for Microsoft 365交互模板
    51CTO博客链接:https://blog.51cto.com/u_13637423即将推出的MicrosoftPurviewCommunicationCompliance是一个新模板,专门用于分析所有CopilotforMicrosoft365提示和响应,预计在2024年1月底正式发布。CommunicationCompliance正在引入一个新模板,专门用于分析所有CopilotforMi......
  • 用我这套模板,几分钟做出文档网站!
    大家好,我是保姆皮,最近我上线了自己的《编程宝典》网站,可以在线阅读我分享过的各种编程学习路线和知识干货。指路:https://codefather.cn/不少小伙伴催我出教程,说也想做个类似的文档网站。所以我用最快的速度出了“保姆级文档网站制作教程”,并且开源了一套网站模板。大家只需要几分......