线段树 transformation——hdu 4578

news/2025/1/15 15:11:57/文章来源:https://www.cnblogs.com/oQAQo/p/18406461

问题描述:
给定一个数列,数列中所有元素都初始化为0,对其执行多种区间操作
操作1:add修改:对区间[L,R]内的所有数加c
操作2:multi修改:对区间[L,R]内所有数乘以c
操作3:change操作:把区间[L,R]内所有数改为c
操作4:sum操作:对区间中的每个数的p次方求和。1<=p<=3
输入:
有不超过10个测试用例。
对于每个测试用例,第一行包含两个数字n和m,表示有n个整数和m个操作。其中,1 <= n, m <= 100,000。
接下来的m行,每行包含一个操作。操作1到3的格式为:"1 x y c" 或 "2 x y c" 或 "3 x y c"。操作4的格式为:"4 x y p"。
(其中,1 <= x <= y <= n,1 <= c <= 10,000,1 <= p <= 3)
输入以0 0结束。
输出:
对于每个操作4,输出一个整数作为结果,每个结果占一行。答案可能非常大,你只需计算答案除以10007的余数即可。

题目分析:
本题考查对lazy_tag标记的理解,有三种修改操作三种查询操作,意味着需要三种tag标记,我们分别定义为add[],multi[],change[]标记,需要知道的是他们在记录变化的时候,存在什么样的关系。
(1)做change修改时,原有的add和multi标记失效
(2)做multi修改时,如果原有add,则将add改为addmulti
(3)做线段树pushdown操作时,先处理change操作,后处理multi,最后执行add
三种查询操作,求和sum1,平方和sum2,立方和sum3。对于change和multi标记三种查询都很容易计算,对于add标记sum求和容易计算,但平方和与立方和需要推倒:
平方和sum2:
(a+c)2=a2+c
c+2ac,即sum2[new]=sum2[old]+(R-L+1)cc+2sum1[old]c
立方和
(a+c)3=a3+ccc+3c(a**2+ac),即sum3[new]=sum3[old]+(R-L+1)ccc+3c(sum2[old]+sum1[old]c)
注:公式还需要结合操作二

代码:
来自园内大佬

#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <math.h>
#include <stdlib.h>
using namespace std;
const int MOD = 10007;
const int MAXN = 100010;
struct Node {int l, r;int sum1, sum2, sum3;int lazy1, lazy2, lazy3;
} segTree[MAXN * 3];
void build(int i, int l, int r) {segTree[i].l = l;segTree[i].r = r;segTree[i].sum1 = segTree[i].sum2 = segTree[i].sum3 = 0;segTree[i].lazy1 = segTree[i].lazy3 = 0;segTree[i].lazy2 = 1;  //乘法标记为1int mid = (l + r) / 2;if (l == r)return;build(i << 1, l, mid);build((i << 1) | 1, mid + 1, r);
}
void push_up(int i) {if (segTree[i].l == segTree[i].r)return;segTree[i].sum1 = (segTree[i << 1].sum1 + segTree[(i << 1) | 1].sum1) % MOD;segTree[i].sum2 = (segTree[i << 1].sum2 + segTree[(i << 1) | 1].sum2) % MOD;segTree[i].sum3 = (segTree[i << 1].sum3 + segTree[(i << 1) | 1].sum3) % MOD;}void push_down(int i) {if (segTree[i].l == segTree[i].r) return;if (segTree[i].lazy3 != 0) {segTree[i << 1].lazy3 = segTree[(i << 1) | 1].lazy3 = segTree[i].lazy3;//加标记改为0,乘标记改为1即可将标记清除,将原有的标记清除segTree[i << 1].lazy1 = segTree[(i << 1) | 1].lazy1 = 0;segTree[i << 1].lazy2 = segTree[(i << 1) | 1].lazy2 = 1;//左孩子节点更新segTree[i << 1].sum1 = (segTree[i << 1].r - segTree[i << 1].l + 1) * segTree[i << 1].lazy3 % MOD;  //csegTree[i << 1].sum2 = (segTree[i << 1].r - segTree[i << 1].l + 1) * segTree[i << 1].lazy3 % MOD * segTree[i << 1].lazy3 % MOD;  //c*csegTree[i << 1].sum3 = (segTree[i << 1].r - segTree[i << 1].l + 1) * segTree[i << 1].lazy3 % MOD * segTree[i << 1].lazy3 % MOD * segTree[i << 1].lazy3 % MOD; //c*c*c//右孩子节点更新segTree[(i << 1) | 1].sum1 = (segTree[(i << 1) | 1].r - segTree[(i << 1) | 1].l + 1) * segTree[(i << 1) | 1].lazy3 % MOD;segTree[(i << 1) | 1].sum2 = (segTree[(i << 1) | 1].r - segTree[(i << 1) | 1].l + 1) * segTree[(i << 1) | 1].lazy3 % MOD * segTree[(i << 1) | 1].lazy3 % MOD;segTree[(i << 1) | 1].sum3 = (segTree[(i << 1) | 1].r - segTree[(i << 1) | 1].l + 1) * segTree[(i << 1) | 1].lazy3 % MOD * segTree[(i << 1) | 1].lazy3 % MOD * segTree[(i << 1) | 1].lazy3 % MOD;//标记传递后需要删除segTree[i].lazy3 = 0;}if (segTree[i].lazy1 != 0 || segTree[i].lazy2 != 1) {int sum1, sum2, sum3;//在做线段树pushdown操作时,先执行change,再执行multi,最后执行add//更新标记segTree[i << 1].lazy1 = (segTree[i].lazy2 * segTree[i << 1].lazy1 % MOD + segTree[i].lazy1) % MOD;segTree[i << 1].lazy2 = segTree[i << 1].lazy2 * segTree[i].lazy2 % MOD;//更新sum,在做线段树pushdown操作时,先执行change,再执行multi,最后执行addsum1 = (segTree[i << 1].sum1 * segTree[i].lazy2 % MOD + (segTree[i << 1].r - segTree[i << 1].l + 1) * segTree[i].lazy1 % MOD) % MOD;sum2 = (segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i << 1].sum2 % MOD + 2 * segTree[i].lazy1 * segTree[i].lazy2 % MOD * segTree[i << 1].sum1 % MOD + (segTree[i << 1].r - segTree[i << 1].l + 1) * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;sum3 = segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i << 1].sum3 % MOD;sum3 = (sum3 + 3 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i << 1].sum2) % MOD;sum3 = (sum3 + 3 * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[i << 1].sum1) % MOD;sum3 = (sum3 + (segTree[i << 1].r - segTree[i << 1].l + 1) * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;segTree[i << 1].sum1 = sum1;segTree[i << 1].sum2 = sum2;segTree[i << 1].sum3 = sum3;segTree[i << 1 | 1].lazy1 = (segTree[i].lazy2 * segTree[i << 1 | 1].lazy1 % MOD + segTree[i].lazy1) % MOD;segTree[i << 1 | 1].lazy2 = segTree[i << 1 | 1].lazy2 * segTree[i].lazy2 % MOD;sum1 = (segTree[i << 1 | 1].sum1 * segTree[i].lazy2 % MOD + (segTree[i << 1 | 1].r - segTree[i << 1 | 1].l + 1) * segTree[i].lazy1 % MOD) % MOD;sum2 = (segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i << 1 | 1].sum2 % MOD + 2 * segTree[i].lazy1 * segTree[i].lazy2 % MOD * segTree[i << 1 | 1].sum1 % MOD + (segTree[i << 1 | 1].r - segTree[i << 1 | 1].l + 1) * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;sum3 = segTree[i].lazy2 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i << 1 | 1].sum3 % MOD;sum3 = (sum3 + 3 * segTree[i].lazy2 % MOD * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i << 1 | 1].sum2) % MOD;sum3 = (sum3 + 3 * segTree[i].lazy2 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[i << 1 | 1].sum1) % MOD;sum3 = (sum3 + (segTree[i << 1 | 1].r - segTree[i << 1 | 1].l + 1) * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD * segTree[i].lazy1 % MOD) % MOD;segTree[i << 1 | 1].sum1 = sum1;segTree[i << 1 | 1].sum2 = sum2;segTree[i << 1 | 1].sum3 = sum3;//传递后需要清除标记segTree[i].lazy1 = 0;segTree[i].lazy2 = 1;}
}
void update(int i, int l, int r, int type, int c) {if (segTree[i].l >= l && segTree[i].r <= r) {//根据公式填写即可c %= MOD;if (type == 1) {segTree[i].lazy1 += c;segTree[i].lazy1 %= MOD;segTree[i].sum3 = (segTree[i].sum3 + 3 * segTree[i].sum2 % MOD * c % MOD + 3 * segTree[i].sum1 % MOD * c % MOD * c % MOD + (segTree[i].r - segTree[i].l + 1) * c % MOD * c % MOD * c % MOD) % MOD;segTree[i].sum2 = (segTree[i].sum2 + 2 * segTree[i].sum1 % MOD * c % MOD + (segTree[i].r - segTree[i].l + 1) * c % MOD * c % MOD) % MOD;segTree[i].sum1 = (segTree[i].sum1 + (segTree[i].r - segTree[i].l + 1) * c % MOD) % MOD;}else if (type == 2) {segTree[i].lazy1 = segTree[i].lazy1 * c % MOD;segTree[i].lazy2 = segTree[i].lazy2 * c % MOD;segTree[i].sum1 = segTree[i].sum1 * c % MOD;segTree[i].sum2 = segTree[i].sum2 * c % MOD * c % MOD;segTree[i].sum3 = segTree[i].sum3 * c % MOD * c % MOD * c % MOD;}else {segTree[i].lazy1 = 0;segTree[i].lazy2 = 1;segTree[i].lazy3 = c % MOD;segTree[i].sum1 = c * (segTree[i].r - segTree[i].l + 1) % MOD;segTree[i].sum2 = c * (segTree[i].r - segTree[i].l + 1) % MOD * c % MOD;segTree[i].sum3 = c * (segTree[i].r - segTree[i].l + 1) % MOD * c % MOD * c % MOD;}return;}push_down(i);//二分int mid = (segTree[i].l + segTree[i].r) / 2;if (l <= mid)update(i << 1, l, r, type, c);if (r > mid)update((i << 1) | 1, l, r, type, c);push_up(i);
}
int query(int i, int l, int r, int p) {if (segTree[i].l >= l && segTree[i].r <= r) {if (p == 1)return segTree[i].sum1;else if (p == 2)return segTree[i].sum2;else return segTree[i].sum3;}push_down(i);int mid = (segTree[i].l + segTree[i].r) / 2;int sum = 0;if (l <= mid) sum += query(i << 1, l, r, p);if (r > mid) sum += query((i << 1) | 1, l, r, p);return sum % MOD;
}int main() {//freopen("in.txt","r",stdin);//freopen("out.txt","w",stdout);int n, m;while (scanf("%d%d", &n, &m) == 2) {if (n == 0 && m == 0)break;build(1, 1, n);int type, x, y, c;while (m--) {scanf("%d%d%d%d", &type, &x, &y, &c);if (type == 4)printf("%d\n", query(1, x, y, c));else update(1, x, y, type, c);}}return 0;
}

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

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

相关文章

第四章 视图(views)

4.视图 4.1 文件or文件夹4.2 相对和绝对导入urls注意实现:不要再项目根目录做相对导入。 原则:绝对导入 相对导入(层级深)4.3 视图参数 urlpatterns = [path(login/, account.login, name="login"),path(auth/, order.auth, name=auth), ]from django.shortcuts …

[设计模式] Cola-StateMachine : 一个轻量实用的Java状态机框架

1 概述:状态机 1.0 状态机 vs 工作流在介绍状态机之前,先介绍一个工作流(WorkFlow),初学者通常容易将两个概念混淆。工作流(WorkFlow),大体是指业务过程(整体或者部分)在计算机应用环境下的自动化,是对工作流程及其各操作步骤之间业务规则的描述。在计算机系统中,工…

Qml 实现瀑布流布局

最近在刷掘金的时候看到一篇关于瀑布流布局的文章,然鹅他们的实现都是前端的那套,就想着 Qml 有没有类似实现。 结果百度了一圈也没有( T_T Qml 凉了凉了 ),于是,我按照自己理解,简单实现了一个 Qml 版的瀑布流布局。【写在前面】 最近在刷掘金的时候看到一篇关于瀑布流布…

Rocky9

Rocky Linux 9.4 部署Zabbix 7.0 1-1.检测源 wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm #下载epel的源 rpm -ivh epel-release-latest-8.noarch.rpm #epel安装 rpm -Uvh https://repo.zabbix.com/zabbix/7.0/rocky/9/x86_64/zabbix-releas…

洛谷题单指南-常见优化技巧-P1714 切蛋糕

原题链接:https://www.luogu.com.cn/problem/P1714 题意解读:求长度不超过m的最大子段和 解题思路: 1、暴力法 设a[N]表示原数组,s[N]是a[N]的前缀和,对于每一个元素s[i],计算其与前m个元素之差,取差值最大值,用代码表示: for(int i = 1; i <= n; i++) {for(int j …

【专题】2024年中国折叠屏手机市场与消费趋势研究报告合集PDF分享(附原数据表

原文链接:https://tecdat.cn/?p=37645 中国智能手机市场目前仍处于整体增长瓶颈期,增长复苏未达预期,消费者换机预期周期不断延长,使得行业对破局点的探寻更为紧迫。与此同时,中端消费者购机呈现出消费降级与升级的分化态势,不过更多人会选择体验更好、配置更优的产品以…

Goby 漏洞发布|(CVE-2024-45195)Apache OFBiz /viewdatafile 代码执行漏洞【已复现】

漏洞名称:Apache OFBiz /viewdatafile 代码执行漏洞(CVE-2024-45195) English Name:Apache OFBiz /viewdatafile Code Execution Vulnerability(CVE-2024-45195) CVSS core: 8.0 漏洞描述: Apache OFBiz是一个开源企业资源规划(ERP)系统。它提供了一套企业应用程序,…

navicat无法连接远程的mysql--Host ‘xx.xx.xx.xx‘ is not allowed to connect to this MySQL server“

之前在远程虚拟机上面部署了mysql,想在本地客户端使用navicat连接数据库,结果提示:host xxx is not allowed to connect to this mysql server解决 出现这个提示,是由于我们使用root用户登录时,没有给root用户设置能访问的机器,所以我们设置一下,就可以了。1:登录mysql…

jQuery中开发插件

页面代码<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title><script s…

ubuntu 使用命令行查看硬件信息

ubuntu 使用命令行查看硬件信息 CPU cat /proc/cpuinfo其中,model name就显示了cpu的型号,cpu cores显示cpu的所有物理核心数量。 内存 cat /proc/meminfo其中,MemTotal就显示总内存大小,这里为32GB内存,SwapTotal显示了交换分区的内存大小,这里为 2GB。 硬盘大小 df -h可…

易百纳ss928开发板移植自训练模型跑通yolov5算法

ss928平台移植官方yolov5s算法参考文章:https://www.ebaina.com/articles/140000017418,这位大佬也开源了代码,gitee链接:https://gitee.com/apchy_ll/ss928_yolov5s 本文在参考上述文章的基础上,将官方yolov5s模型跑通,验证推理图片正确,然后移植自训练的推理模型,在移…