[HDU - 4578]Transformation(线段树+多重懒标记)

news/2024/4/25 16:21:36/文章来源:https://blog.csdn.net/weixin_72060925/article/details/130349306

[HDU - 4578]Transformation(线段树+多重懒标记)

  • 一、问题
  • 二、分析
    • 1、节点定义
    • 2、pushup
    • 3、pushdown
      • (1)每种标记如何下传?
        • 赋值
        • 乘法
        • 加法
      • (2)三种标记下传的优先级问题
  • 三、代码

一、问题

在这里插入图片描述

二、分析

这道题涉及到了区间操作,所以我们用线段树算法。同时,这道题里面有区间修改的操作,所以我们还要用到懒标记。

这里一共有三种区间的操作,分别是:加、乘、赋值。这三种操作无法用一个懒标记来统一,所以我们需要使用三个懒标记来完成这道题。

这道题的查询操作也分为三种,一次方的和、二次方的和、三次方的和。

所以我们需要去维护三种 s u m sum sum

1、节点定义

/*
tag_1 --> 加法
tag_2 --> 乘法
tag_3 --> 赋值
*/
struct Node
{int l, r;int sum1, sum2, sum3;int tag_1, tag_2, tag_3;
}tre[N * 4];

2、pushup

p u s h u p pushup pushup函数就是利用子节点来更新父节点,这个操作比较简单,直接合并三种和即可。

//lson 是左儿子, rson是右儿子
void pushup(int u)
{tre[u].sum1 = (tre[lson].sum1 + tre[rson].sum1) % mod;tre[u].sum2 = (tre[lson].sum2 + tre[rson].sum2) % mod;tre[u].sum3 = (tre[lson].sum3 + tre[rson].sum3) % mod;
}

3、pushdown

p u s h d o w n pushdown pushdown操作是将三种懒标记下传的操作。这里需要注意两个问题:
1、每种标记如何下传?
2、三种标记之间下传的优先级问题。

(1)每种标记如何下传?

赋值

赋值公式如下图所示:
在这里插入图片描述
l e n = r − l + 1 len = r - l + 1 len=rl+1
另外需要注意在计算过程中进行取模。

乘法

如下图所示:
在这里插入图片描述
提取公因式即可。

加法

加法是最难处理的,分类讨论一下。
先说一次方。
在这里插入图片描述
再说二次方
在这里插入图片描述
最后说三次方
在这里插入图片描述

(2)三种标记下传的优先级问题

对于某一个区间而言,三种操作可能同时出现。当出现赋值操作的时候,说明在此操作之前出现的加、乘都没有用了,因为都被当前的赋值操作覆盖掉了。所以我们最先考虑的是赋值操作。

如果该区间没有赋值操作,我们考虑的就是乘法操作,乘法出现的时候,说明在此次操作之前的加法操作的数值p也同样需要翻对应的倍数。

最后我们考虑加法。

综合上述讨论,我们可以写出下面的函数实现:

另外我们需要注意,在下传的过程中,我们要将左右区间的标记转化到对应的数值上。

void pushdown(int u)
{auto &root = tre[u], &left = tre[lson], &right = tre[rson];if(root.tag_3){int c = root.tag_3;int len1 = (left.r - left.l + 1);left.sum1 = len1 * c % mod;left.sum2 = len1 * c * c % mod;left.sum3 = len1 * c % mod * c % mod * c % mod;int len2 = (right.r - right.l + 1);right.sum1 = len2 * c % mod;right.sum2 = len2 * c * c % mod;right.sum3 = len2 * c * c * c % mod;left.tag_3 = right.tag_3 = c;left.tag_1 = right.tag_1 = 0;left.tag_2 = right.tag_2 = 1;root.tag_3 = 0;}if(root.tag_2 != 1){int c = root.tag_2;left.sum1 = left.sum1 * c % mod;left.sum2 = left.sum2 * c * c % mod;left.sum3 = left.sum3 * c * c * c % mod;right.sum1 = right.sum1 * c % mod;right.sum2 = right.sum2 * c * c % mod;right.sum3 = right.sum3 * c * c * c % mod;		right.tag_2 = c * right.tag_2 % mod;left.tag_2 = c * left.tag_2 % mod;right.tag_1 = c * right.tag_1 % mod;left.tag_1 = c * left.tag_1 % mod;root.tag_2 = 1; }if(root.tag_1){int c = root.tag_1;int s1 = left.sum1;int s2 = left.sum2;int len1 = left.r - left.l + 1;left.sum1 = (left.sum1 + len1 * c) % mod;left.sum2 = (left.sum2 + 2 * s1 * c + len1 * c * c) % mod;left.sum3 = (left.sum3 + 3 * c * s2 + 3 * s1 * c * c + len1 * c * c * c) % mod;s1 = right.sum1;s2 = right.sum2;int len2 = right.r - right.l + 1;right.sum1 = (right.sum1 + len2 * c) % mod;right.sum2 = (right.sum2 + 2 * s1 * c + len2 * c * c % mod) % mod;right.sum3 = (right.sum3 + 3 * c * s2 % mod + 3 * s1 * c * c % mod + len2 * c % mod * c % mod * c % mod ) % mod;left.tag_1 = (c + left.tag_1) % mod;right.tag_1 = (c + right.tag_1) % mod;root.tag_1 = 0;}
}

以上就是这道题所有的难点,剩下的函数操作就比较常规了。大家直接看代码实现即可。

三、代码

#include<bits/stdc++.h>
#define endl '\n'
#define INF 0x3f3f3f3f
#define lson u << 1
#define rson u << 1 | 1
#define int long long
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N = 1e5 + 10;
const int mod = 1e4 + 7;
int n, m;
struct Node
{int l, r;int sum1, sum2, sum3;int tag_1, tag_2, tag_3;
}tre[N * 4];void pushup(int u)
{tre[u].sum1 = (tre[lson].sum1 + tre[rson].sum1) % mod;tre[u].sum2 = (tre[lson].sum2 + tre[rson].sum2) % mod;tre[u].sum3 = (tre[lson].sum3 + tre[rson].sum3) % mod;
}void pushdown(int u)
{auto &root = tre[u], &left = tre[lson], &right = tre[rson];if(root.tag_3){int c = root.tag_3;int len1 = (left.r - left.l + 1);left.sum1 = len1 * c % mod;left.sum2 = len1 * c * c % mod;left.sum3 = len1 * c % mod * c % mod * c % mod;int len2 = (right.r - right.l + 1);right.sum1 = len2 * c % mod;right.sum2 = len2 * c * c % mod;right.sum3 = len2 * c * c * c % mod;left.tag_3 = right.tag_3 = c;left.tag_1 = right.tag_1 = 0;left.tag_2 = right.tag_2 = 1;root.tag_3 = 0;}if(root.tag_2 != 1){int c = root.tag_2;left.sum1 = left.sum1 * c % mod;left.sum2 = left.sum2 * c * c % mod;left.sum3 = left.sum3 * c * c * c % mod;right.sum1 = right.sum1 * c % mod;right.sum2 = right.sum2 * c * c % mod;right.sum3 = right.sum3 * c * c * c % mod;		right.tag_2 = c * right.tag_2 % mod;left.tag_2 = c * left.tag_2 % mod;right.tag_1 = c * right.tag_1 % mod;left.tag_1 = c * left.tag_1 % mod;root.tag_2 = 1; }if(root.tag_1){int c = root.tag_1;int s1 = left.sum1;int s2 = left.sum2;int len1 = left.r - left.l + 1;left.sum1 = (left.sum1 + len1 * c) % mod;left.sum2 = (left.sum2 + 2 * s1 * c + len1 * c * c) % mod;left.sum3 = (left.sum3 + 3 * c * s2 + 3 * s1 * c * c + len1 * c * c * c) % mod;s1 = right.sum1;s2 = right.sum2;int len2 = right.r - right.l + 1;right.sum1 = (right.sum1 + len2 * c) % mod;right.sum2 = (right.sum2 + 2 * s1 * c + len2 * c * c % mod) % mod;right.sum3 = (right.sum3 + 3 * c * s2 % mod + 3 * s1 * c * c % mod + len2 * c % mod * c % mod * c % mod ) % mod;left.tag_1 = (c + left.tag_1) % mod;right.tag_1 = (c + right.tag_1) % mod;root.tag_1 = 0;}
}void build(int u, int l, int r)
{if(l == r){tre[u] = {l, r};tre[u].tag_2 = 1;return;}int mid = l + r >> 1;tre[u] = {l, r};tre[u].tag_2 = 1;build(lson, l, mid);build(rson, mid + 1, r);
}void modify(int u, int l, int r, int c, int op)
{if(tre[u].l >= l && tre[u].r <= r){auto &root = tre[u];if(op == 1){int s1 = root.sum1;int s2 = root.sum2;root.sum1 = (root.sum1 + (root.r - root.l + 1) * c) % mod;root.sum2 = (root.sum2 + 2 * s1 * c % mod + (root.r - root.l + 1) * c % mod * c % mod) % mod;root.sum3 = (root.sum3 + 3 * c * s2 % mod + 3 * s1 * c * c % mod + (root.r - root.l + 1) * c % mod * c * c % mod ) % mod;root.tag_1 = (c + root.tag_1) % mod;}else if(op == 2){root.sum1 = root.sum1 * c % mod;	root.sum2 = root.sum2 * c * c % mod;root.sum3 = root.sum3 * c % mod * c % mod * c % mod;root.tag_2 = c * root.tag_2 % mod;root.tag_1 = c * root.tag_1 % mod;}else{root.sum1 = (root.r - root.l + 1) * c % mod;root.sum2 = (root.r - root.l + 1) * c * c % mod;root.sum3 = (root.r - root.l + 1) * c % mod * c % mod * c % mod;root.tag_3 = c;root.tag_1 = 0;root.tag_2 = 1;}return;}pushdown(u);int mid = tre[u].l + tre[u].r >> 1;if(l <= mid)modify(lson, l, r, c, op);if(r > mid)modify(rson, l, r, c, op);pushup(u);
}int query(int u, int l, int r, int op)
{if(tre[u].l >= l && tre[u].r <= r){if(op == 1)return tre[u].sum1;else if(op == 2)return tre[u].sum2;elsereturn tre[u].sum3;}int mid = tre[u].l + tre[u].r >> 1;int res = 0;pushdown(u);if(l <= mid)res = (res + query(lson, l, r, op)) % mod;if(r > mid)res = (res + query(rson, l, r, op)) % mod;return res;
}void solve()
{while(cin >> n >> m, n || m){memset(tre, 0, sizeof tre);build(1, 1, n);while(m--){int opt, l, r, c;cin >> opt >> l >> r >> c;if(opt != 4)modify(1, l, r, c, opt);elsecout << query(1, l, r, c) << endl;}}
}signed main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);solve();
}

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

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

相关文章

C++数据结构:手撕AVL树

目录 一. 什么是AVL树 二. AVL树的节点定义 三. AVL树的插入操作 3.1 寻找插入位置 3.2 更新平衡因子 3.3 AVL树的旋转调整 3.4 AVL树插入操作的整体实现 四. AVL树的检验 附录&#xff1a;AVL树的实现完整代码 AVL树定义代码 -- AVLTree.h AVL树检验代码 -- test.…

MFC加载动态gif图片文件C++语言,基于MFC的动画播放控件

MFC加载动态gif图片&#xff0c;使用VS2015环境 一、将下载的PictureEx.h和PictureEx.cpp放在工程文件的目录下&#xff0c;动态gif图片放在工程文件的res文件夹下&#xff1b;&#xff08;GIF动图下载 https://icons8.com/preloaders/en/search/move&#xff09; &#xff08…

软考软件设计师 操作系统笔记

操作系统地位 程序顺序执行&#xff08;进程管理&#xff09; 程序顺序执行的特征&#xff0c;顺序性封闭性可再现性 前趋图 P1结束后 V操作 SS1 P2操作前先执行S S -1 此时S0 一个箭头对应一个信号量 程序并发执行和前驱图 找到输入i计算c输出p&#xff0c;如果找不到就…

“老司机”机器视觉工程师警告,硬件,软件,固件,程序使用新版本务必谨慎

做任何事情之前&#xff0c;程序先保存。没保存&#xff0c;真的会哭的。千万别保存在系统盘。​ 机器视觉最终的目的解决是什么问题&#xff1f;项目验收结束。 如果公司不知道或者希望去测试新的东西&#xff0c;要积极主动去使用&#xff0c;也会学到很多新的东西&#xff…

Java版本企业电子招投标采购系统源代码——功能模块功能描述+数字化采购管理 采购招投标

​ 功能模块&#xff1a; 待办消息&#xff0c;招标公告&#xff0c;中标公告&#xff0c;信息发布 描述&#xff1a; 全过程数字化采购管理&#xff0c;打造从供应商管理到采购招投标、采购合同、采购执行的全过程数字化管理。通供应商门户具备内外协同的能力&#xff0c;为外…

塔望食研院丨百年益生菌,千亿市场正蓝海!

2022年12月塔望咨询开设塔望食品大健康消费研究院&#xff08;简称塔望食研院&#xff09;栏目&#xff0c;塔望食研院以“为食品行业品牌高质量发展赋能”为理念&#xff0c;将不定期发布食品大健康行业研究、消费研究报告。塔望食研院致力于结合外部数据、消费调研数据、企业…

Mybatis学习基础篇(一)——使用Maven快速搭建一个mybatis项目,并实现简单的增删改查

题外话&#xff1a; 在了解mybatis框架之前&#xff0c;我先说明一句&#xff0c;目前主流的框架技术层出不穷&#xff0c;每个人都有自己喜欢的技术框架&#xff0c;自己喜欢用就行。技术并没有高低之分&#xff0c;喜欢用就用&#xff0c;虽然目前大部分人都喜欢向新技术看齐…

C++、STL标准模板库和泛型编程 ——迭代器、 算法、仿函数(侯捷)

C、STL标准模板库和泛型编程 ——迭代器、 算法、仿函数 &#xff08;侯捷&#xff09; 迭代器iterator_category 算法accumulatefor_eachreplacecountfindsortbinary_search 仿函数 functors(六大部件中最简单的一种&#xff01;) 使用一个东西&#xff0c;却不明白它的道理&a…

4月21日第壹简报,星期五,农历三月初二

4月21日第壹简报&#xff0c;星期五&#xff0c;农历三月初二坚持阅读&#xff0c;静待花开1. 推特拒向大模型免费开放数据&#xff01;马斯克威胁起诉微软&#xff1b;Reddit宣布不再向大模型免费开放数据&#xff0c;要求科技巨头付费使用API接口。2. 浙江&#xff1a;鼓励杭…

2023.04.24 c++第六讲

作业&#xff1a; 1. 手动实现顺序栈&#xff0c;要求实现数据结构中&#xff0c;所有栈的相关操作 #include <iostream> #define MAXSIZE 20 //宏定义&#xff0c;栈的最大容量 using namespace std;template <typename T> class stacklink { pri…

FBEC大会 | 瑞云科技 CTO 赵志杰:元宇宙时代的基础设施——实时云渲染

​ FBEC未来商业生态链接大会于2023年2月24日在深圳福田大中华喜来登酒店盛大召开&#xff0c;本次大会由广东省游戏产业协会、深圳市互联网文化市场协会指导&#xff0c;陀螺科技主办。 大会以“勇毅前行逐光而上”为主题&#xff0c;以具有行业前瞻洞察的“探索者”为视角&a…

Three.js+TypeScript+Webpack学习记录(二)

使用环境参考 Node.js v16.19.1 正文 跟着文档画个线 看看 Three 的官方文档&#xff0c;起步 -> 画线 -> 没了&#xff1f;&#xff01;&#xff01; 不管怎么说&#xff0c;先画个线吧。 import * as THREE from threeconst scene new THREE.Scene() const camer…

PyTorch深度学习实战 | 基于深度学习的电影票房预测研究

基于深度学习的映前票房预测模型(Cross&Dense网络结构模型)&#xff0c;该模型通过影片基本信息如&#xff1a;电影类型、影片制式、档期和电影的主创阵容和IP特征等信息对上映影片的票房进行预测。 本篇采用451部电影作为训练模型&#xff0c;最后再在194部影片上进行测试…

【计网 从头自己构建协议】一、libpcap 介绍 手撕以太网帧

上一篇&#xff1a;IndexError: list index out of range 下一篇&#xff1a;[【计网 从头自己构建协议】二、收发 ARP 请求帧与响应帧] 介绍 理论的学习总是枯燥的&#xff0c;想要加深对理论的理解&#xff0c;最好的方法就是自己实践一遍。 想要亲手实现各种协议&#xf…

【音视频第17天】RTSP、RTMP协议初识

被叫去搞直播了&#xff0c;悲喜交加。先学习一下基本的技术栈&#xff0c;RTSP RTMP HTTP 先简单随便看看吧。 目录 什么是流媒体协议RTMPRTMP 工作原理 RTSPRTSP 工作原理 RTMP 与 RTSP 区别详细看看RTSP简介RTSP交互流程OPTIONSDESCRIBESETUPPLAYPAUSESET_PARAMETERGET_PAR…

春招,进阿里了....

个人背景是东北某 985 科班本硕&#xff0c;做的 测试开发&#xff0c;有两个自己写的小项目。下面是一些印象比较深刻的面试题 阿里一面 什么是软件测试&#xff1f; 软件测试过程中会面向哪些群体&#xff1f; 开发一个软件都要经过哪些阶段&#xff1f; 什么是黑盒测试&…

八年软件测试生涯,是时候做出改变了

五年前&#xff0c;我在南方的大城市&#xff1a;广州&#xff0c;做着一个快乐的游戏测试&#xff0c;工作不太忙&#xff0c;对一切技术充满了好奇心。测试工作不专业&#xff0c;也不受重视。但我有自己的快乐。工作不忙的时候&#xff0c;我今天学学Python&#xff0c;明天…

什么是客户服务平台?

在社交媒体和智能手机出现之前&#xff0c;品牌主要通过单向广告渠道与客户互动。社交媒体打破了这种自上而下的动态&#xff0c;以前所未有的方式打开了对话&#xff0c;将客户包括在内。 品牌不再控制客户对人们分享公司内容的行为。人们可以点击离开&#xff0c;向左滑动&a…

Python-pyppeteer解决微软Microsoft的登录机器人验证(8)

前言 本文是该专栏的第8篇,结合优质项目案例,让你精通使用Pyppeteer,后面会持续分享Pyppeteer的干货知识,记得关注。 在注册微软Microsoft账号或者注册outlook邮箱账号的时候,会遇到如下机器人验证: 是的,你可能第一眼看到这个验证页面,首先会想到是定位它的页面元素N…

非常详细的阻抗测试基础知识

编者注&#xff1a;为什么要测量阻抗呢&#xff1f;阻抗能代表什么&#xff1f;阻抗测量的注意事项... ...很多人可能会带着一系列的问题来阅读本文。不管是数字电路工程师还是射频工程师&#xff0c;都在关注各类器件的阻抗&#xff0c;本文非常值得一读。全文13000多字&#…