牛牛的等差数列【线段树】

2023-11-12


题目链接


  这里的突破口在于小于等于25且大于等于3的质数连乘在1e8左右,所以,我们可以在操作上,将其看作对1e8去求模,而不是对每个都进行预处理。

时间复杂度O(N log(N) * 8)\rightarrow O(N log(N))。也就是说,我们排除这个预处理之后,直接就是降了10倍左右的复杂度。

  然后,给区间一个等差数列,可以看成给这段区间赋一个基础值和递增一个值,所以我们在线段树上操作的时候,维护两个懒标记,分别是基础值,和等差值。因为存在累加(线性)关系,所以直接利用累加即可。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <bitset>
//#include <unordered_map>
//#include <unordered_set>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
#define INF 0x3f3f3f3f
#define Big_INF 0x3f3f3f3f3f3f3f3f
#define eps 1e-8
#define HalF (l + r)>>1
#define lsn rt<<1
#define rsn rt<<1|1
#define Lson lsn, l, mid
#define Rson rsn, mid+1, r
#define QL Lson, ql, qr
#define QR Rson, ql, qr
#define myself rt, l, r
#define MP(a, b) make_pair(a, b)
using namespace std;
typedef unsigned long long ull;
typedef unsigned int uit;
typedef long long ll;
const int maxN = 2e5 + 7;
const ull mod[8] = {3, 5, 7, 11, 13, 17, 19, 23};
const ull MOD = 3 * 5 * 7 * 11 * 13 * 17 * 19 * 23;
inline int _ID(ull mx) { return (int)(lower_bound(mod, mod + 8, mx) - mod); }
int N, Q;
ull a[maxN], tree[maxN << 2], sum[maxN << 2], del[maxN << 2];
bool lazy[maxN << 2] = {false};
inline void pushup(int rt) { tree[rt] = (tree[lsn] + tree[rsn]) % MOD; }
void buildTree(int rt, int l, int r)
{
    if(l == r) { tree[rt] = a[l] % MOD; return; }
    int mid = HalF;
    buildTree(Lson); buildTree(Rson);
    pushup(rt);
}
inline void pushdown(int rt, int l, int r)
{
    if(lazy[rt])
    {
        int mid = HalF; ull len_L = mid - l + 1, len_R = r - mid;
        lazy[lsn] = lazy[rsn] = true;
        sum[lsn] = (sum[lsn] + sum[rt]) % MOD;
        del[lsn] = (del[lsn] + del[rt]) % MOD;
        tree[lsn] = (tree[lsn] + sum[rt] * len_L + (len_L - 1LL) * len_L / 2LL % MOD * del[rt] % MOD) % MOD;
        sum[rsn] = (sum[rsn] + sum[rt] + del[rt] * len_L) % MOD;
        del[rsn] = (del[rsn] + del[rt]) % MOD;
        tree[rsn] = (tree[rsn] + (sum[rt] + del[rt] * len_L) % MOD * len_R + (len_R - 1LL) * len_R / 2LL % MOD * del[rt]) % MOD;
        sum[rt] = del[rt] = 0;
        lazy[rt] = false;
    }
}
void update(int rt, int l, int r, int ql, int qr, ull val, ull d)
{
    if(ql <= l && qr >= r)
    {
        ull fir_v = (val + d * (l - ql)) % MOD;
        lazy[rt] = true;
        sum[rt] = (sum[rt] + fir_v) % MOD;
        del[rt] = (del[rt] + d) % MOD;
        tree[rt] = (tree[rt] + fir_v * (r - l + 1) % MOD + (ull)(r - l) * (r - l + 1) / 2LL * d) % MOD;
        return;
    }
    pushdown(myself);
    int mid = HalF;
    if(qr <= mid) update(QL, val, d);
    else if(ql > mid) update(QR, val, d);
    else { update(QL, val, d); update(QR, val, d); }
    pushup(rt);
}
ull query(int rt, int l, int r, int ql, int qr, int op)
{
    if(ql <= l && qr >= r) return tree[rt] % mod[op];
    pushdown(myself);
    int mid = HalF;
    if(qr <= mid) return query(QL, op);
    else if(ql > mid) return query(QR, op);
    else return (query(QL, op) + query(QR, op)) % mod[op];
}
int main()
{
    scanf("%d", &N);
    for(int i=1; i<=N; i++) scanf("%lld", &a[i]);
    buildTree(1, 1, N);
    scanf("%d", &Q); int op, l, r, v, d;
    while(Q--)
    {
        scanf("%d", &op);
        if(op == 1)
        {
            scanf("%d%d%d%d", &l, &r, &v, &d);
            update(1, 1, N, l, r, v, d);
        }
        else
        {
            scanf("%d%d%d", &l, &r, &d);
            printf("%lld\n", query(1, 1, N, l, r, _ID(d)));
        }
    }
    return 0;
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

牛牛的等差数列【线段树】 的相关文章

  • VMware Tools安装(实现物理机与虚拟机文件互拷)

    1 开启虚拟机 2 点击VMware菜单上的虚拟机 弹出的菜单中点击安装VMware Tools 3 点击DVD 出现右边如图 4 复制VMware Tools压缩文件到opt文件夹 复制时可能出现下图描述 5 解决方法 1 打开终端 输入
  • 你了解System.out.println()的真正含义吗?

    在Java编程中 我们常常用 System out println 来输出字符串 也许我们都已经猜到println 是方法名 但System是什么 out又是什么呢 其实System是java lang里面的一个类 如下图 而out就是Sy

随机推荐

  • IDEA中/** 内容 */注释的快捷键

    在 IDEA 中 你可以使用快捷键 来快速生成 内容 注释 要使用此快捷键 请在你想要添加注释的代码行上按 Ctrl Windows 系统 或 Command Mac 系统 如果你想要撤销注释 可以再次按一次快捷键即可 注意 你必须在代码行
  • 设计模式学习笔记(七)之模板方法模式(Template Method)

    设计模式学习笔记 七 之模板方法模式 Template Method 最近实习工作稍微没有那么忙了 继续抽些晚上时间学习一下设计模式 以下是看设计模式书的学习笔记 关于模式定义之类的内容是在自己理解之后进行摘录的 希望对大家有用 代码下载链
  • SpringBoot获取微信公众号(小程序)access_token 使用Redis存储

    文章目录 前言 一 导入依赖 二 编写配置 1 personal yaml配置文件 2 WeChatBean实体类 3 编写RestTemplateConfig 4 开启定时任务 三 实现生成和存储access token 1 基本介绍 2
  • 路飞IT全学科实战项目5年黑金卡

    正在代理路飞IT全学科实战项目5年黑金卡 文末有联系方式 包含Python开发 Linux云计算 前端开发 Golang开发 AI 数据分析 网络安全 技术生涯 C语言 JAVA开发 测试 PHP 视频讲解 项目源码内容非常详细 开通黑金卡
  • 浅入深谈:如何更好地理解面向对象编程与面向过程编程的本质区别?

    今天 我们以一个例子 如打扫房间 来说明面向过程和面向对象在程序流程上的不同之处 在菜鸟分析看来 面向过程就是将编程当成是做一件事 要按步骤完成 每一步就是一个过程 比如菜鸟分析要打扫房间这件事 需要先取扫帚 然后仔仔细细打扫每一处 最后将
  • springboot理论知识汇总(图文解析)

    MVC HTTP请求处理流程 参数绑定 不同注解修饰的参数都有支持的方法参数处理器 例如 RequestParam对应的是RequestParamMethodArgumentResolver 在请求处理流程中的调用目标方法环节 会使用对应的
  • 语义分割混淆矩阵、 mIoU、mPA计算

    一 操作 import cv2 img gray cv2 imread nezha jpg cv2 IMREAD GRAYSCALE for i in range 22 dst cv2 applyColorMap img gray i cv
  • Scratch基础-积木讲解-必学(2000字)

    上次那篇文章有小伙伴跟Rocky丶说教程看不大懂 那我今天来给大家分享自己对scratch中每一个积木的认识 运用 后半部分Rocky丶可能没时间更新了 因为要上课 作业做不完 而且初三任务较重 我让我的好朋友PLTS帮我慢慢补咯 希望CS
  • vs2010环境下提示找不到d3dx9.h

    无法打开d3dx9 h 我们知道d3dx9 h是在DirectX SDK中的 我们只是需要下载下来就可以了 下载地址为 http www microsoft com en us download details aspx id 6812 如
  • 如何在 Luminar 4 中​使用AI天空更换工具?

    如何在 Luminar 4 中使用AI天空更换工具 如果照片缺少引人入胜的天空 AI天空更换工具可以轻松替换它 该工具设计用于平坦或暴风雨的天空 但通常可以通过改进滑块进行调整以适用于大多数天空 AI天空更换工具利用人工智能的力量自动分析图
  • 【JavaScript】(一)类型转换

    JS支持自动类型转换 其功能非常强大 首先看一段代码 结果如下 由此可见执行减法运算的时候 自动执行算术运算 但是执行加法运算的时候 默认将 作为连接符 它的转换规律如下 对于减号运算符 因为字符串不支持减法运算 所以系统自动将字符串转换成
  • Loongnix单机部署Ceph(LoongArch架构、Ceph N版、手动部署MON、OSD、MGR、Dashboard服务)

    基础环境信息 CPU 龙芯3C5000L 2 内存 128G 硬盘 系统盘 一块512G的NVME的SSD 数据盘 三块16T的HDD 操作系统版本 Loongnix 8 4 Ceph版本 Ceph 14 2 21 Nautilus Cep
  • java中优雅的参数校验方法

    一 引子 要对方法的参数进行校验 最简单暴力的写法是这个样子 public static void utilA String a BigDecimal b if StringUtils isEmpty a System out printl
  • java-FileReader和FileWriter的介绍

    在java中对数据输入输出的操作陈作为流 我们对不同的文件进行操作 或者对操作文件进行输入和输出时所用的流都是不同的 因此在java io的包下存在很多流的类或者接口提供给我们对应的操作 流的原理 输入流 input 将外部的文件通过流读取
  • css3中vh和vw分别是什么意思?

    1vw等于视口宽度 viewport width 的百分之一 也就是说100vw就是视口的宽度 同理 1vh等于视口高度 viewport height 的百分之一 100vh就是视口的高度
  • 位运算高级应用

    位运算的高级应用 位运算符 针对整数的二进制 下面的数据假设为1字节 实际为4字节 12 0000 1100 13 0000 1101 12 13 0000 1100 按位与 相同的位都为1才为1 12 13 0000 1101 按位或 相
  • 了解Linux虚拟化

    了解Linux虚拟化 本章为读者提供了Linux虚拟化中的主流技术及其相对于其他技术的优势的见解 本书共有14章 涵盖了KVM虚拟化的所有重要方面 从KVM内部和高级主题 如软件定义的网络 性能调整和优化 到物理到 虚拟迁移开始 在本章中
  • ubuntu安装ssh

    1 检查自己是否安装了openssh server dpkg l grep ssh 如果输出内容有openssh server 说明已经安装过了 可以跳过下一步 2 安装openssh server 由于ubuntu自带ssh客户端 只需要
  • docker 命令报异常permission denied

    在Linux系统中 新安装docker 输入命令 如 docker images 结果却报异常了 简单理解就是当前用户的连接被拒绝了 解决方案一 使用管理员权限 命令前加sudo 解决方案二 给当前用户加入到docker用户组中 sudo
  • 牛牛的等差数列【线段树】

    题目链接 这里的突破口在于小于等于25且大于等于3的质数连乘在1e8左右 所以 我们可以在操作上 将其看作对1e8去求模 而不是对每个都进行预处理 时间复杂度 也就是说 我们排除这个预处理之后 直接就是降了10倍左右的复杂度 然后 给区间一