[忘发了]P3710 方方方的数据结构

news/2025/11/14 10:35:42/文章来源:https://www.cnblogs.com/lymsHz17/p/19220854

我!卡!了!一!晚!上!常!

真是有趣极了,发现和题解区现有的卡常方式不同,为缓解心中不适,故记录。

正文

这段不难,略讲。

没有删除操作的话这题就可以直接线段树维护,因为有删除,所以考虑处理删除。

一个比较容易的方法就是直接暴力重构所有操作,但是显然不行。

考虑对着操作序列分块,处理出某位置上的一个数字 \(x\) 经过这一块后会变成的 \(ax+b\)\(a\)\(b\)

你发现这是很简单的线段树操作,而且分块维护可以保证查询和重构的复杂度都是 \(\sqrt m \log n\) 的。

然后就完了。

接下来都是重要的卡常技巧。

卡常

先来两句和写法无关的卡常方式。

老生常谈,快读,调块长,不要 #define int long long

以及用 uint 代替 int,这样据说取模会快点。

然后是写法方面。

首先可以懒重构,到下一次查询的时候再重构,会快很多。

然后是发现既然要重构,那么从有删除开始就别再修改了,等着重构就行,会快很多。

以及很重要的是要离散化,逐块离散化,会快很多。同时对着 \(l,r,l-1,r+1\) 离散化就可以避免出现多查漏查,这样处理可以少很多分讨。

然后另一个比较重要的点是,线段树你只需要维护懒标记就行了,不用维护 \(a\)\(b\) 具体的值,因为它是单点查询,而对于单点,也就是线段树底层,懒标记和它的值是等价的。

以及把暴力回收节点的重构改成用懒标记清空不知道会不会快,总之我知道会更难写。

代码说是:

// code by 樓影沫瞬_Hz17
#include <bits/stdc++.h>#define getc() getchar_unlocked()
#define putc(a) putchar_unlocked(a)
#define en_ putc('\n')
#define e_ putc(' ')using std::cout;
using std::cerr;template<class T> inline T in() { T n = 0; char p = getc();while(p < '-') p = getc();bool f = p == '-' ? p = getc() : 0;do n = n * 10 + (p ^ 48), p = getc();while(isdigit(p));return f ? -n : n;
}
template<class T> inline T in(T &a) { return a = in<T>(); }
template<class T, class ... Args> inline void in(T &t, Args&... args) { in(t), in(args...); }template<class T> inline void out(T n) {if(n < 0) putc('-'), n = -n;if(n > 9) out(n / 10);putc(n % 10 + '0');
}template<class T1, class T2> T1 max(T1 a, T2 b) { return a > b ? a : a = b;}
template<class T1, class T2> T1 min(T1 a, T2 b) { return a < b ? a : a = b;}constexpr uint N = 15e4 + 10, mod = 998244353, B = 450;uint n, m;
std::vector<uint> x[N / B + 10];
struct val {uint times, plus;val() { times = 1; }val(uint i, uint j) { times = j, plus = i; }void init() { times = 1, plus = 0; }
} ;
struct node {val tag;uint l, r;node() {}void init() { l = r = 0, tag.init(); }
} ;
node t[N * 25];
uint pool[N * 25], tp;struct Block {struct Tree {inline uint append() {uint u = pool[tp --];t[u].init();stk.emplace_back(u);return u;}std::vector<uint> stk;inline void down(uint u) {if(t[u].tag.times != 1) {if(!t[u].l) t[u].l = append();if(!t[u].r) t[u].r = append();t[t[u].l].tag.times = 1ull * t[t[u].l].tag.times * t[u].tag.times % mod;t[t[u].l].tag.plus = 1ull * t[t[u].l].tag.plus * t[u].tag.times % mod;t[t[u].r].tag.times = 1ull * t[t[u].r].tag.times * t[u].tag.times % mod;t[t[u].r].tag.plus = 1ull * t[t[u].r].tag.plus * t[u].tag.times % mod;t[u].tag.times = 1; }if(t[u].tag.plus) {	if(!t[u].l) t[u].l = append();												   if(!t[u].r) t[u].r = append();													t[t[u].l].tag.plus = (t[t[u].l].tag.plus + t[u].tag.plus) % mod;t[t[u].r].tag.plus = (t[t[u].r].tag.plus + t[u].tag.plus) % mod;t[u].tag.plus = 0;}}#define mid ((l + r) >> 1)inline void updatePlus(uint&u, uint l, uint r, uint L, uint R, uint add) {if(!u) u = append();if(L <= l and r <= R) return void(t[u].tag.plus = (add + t[u].tag.plus) % mod);down(u);if(L <= mid) updatePlus(t[u].l, l, mid, L, R, add);if(R > mid) updatePlus(t[u].r, mid + 1, r, L, R, add);}inline void updateTimes(uint&u, uint l, uint r, uint L, uint R, uint add) {if(!u) u = append();if(L <= l and r <= R) return void((t[u].tag.plus = 1ull * t[u].tag.plus * add % mod) | (t[u].tag.times = 1ull * t[u].tag.times * add % mod));down(u);if(L <= mid) updateTimes(t[u].l, l, mid, L, R, add);if(R > mid) updateTimes(t[u].r, mid + 1, r, L, R, add);}inline val query(uint u, uint l, uint r, uint p) {if(!u) return {0, 1};if(l == r) return t[u].tag;down(u);if(p <= mid) return query(t[u].l, l, mid, p);return query(t[u].r, mid + 1, r, p);}#undef midinline void clear() { for(uint v : stk) pool[++ tp] = v;stk.clear();}} ;uint neq;Tree tr; uint rt;struct Calc {uint l, r, op, d, id;} ;std::vector<Calc> calc;using iter = std::vector<Calc>::iterator;bool changed;inline void Rebuild() {tr.clear(), rt = 0;for(Calc it : calc) {if(it.op == 1) tr.updatePlus(rt, 0, neq, it.l, it.r, it.d);if(it.op == 2) tr.updateTimes(rt, 0, neq, it.l, it.r, it.d);}}inline void Erase(uint id) {changed = 1;for(iter it = calc.begin(); it != calc.end(); it ++) if(it->id == id) {calc.erase(it);break;}}inline void Insert(Calc it) {calc.emplace_back(it);if(changed) return;if(it.op == 1) tr.updatePlus(rt, 0, neq, it.l, it.r, it.d);if(it.op == 2) tr.updateTimes(rt, 0, neq, it.l, it.r, it.d);}inline void Query(uint&x, uint pos) {if(changed) {changed = 0;Rebuild();}val end = tr.query(rt, 0, neq, pos);x = (1ull * x * end.times + end.plus) % mod;}Block() { changed = 0; rt = 0; }
} A[N / B + 10];uint pos[N];
struct czm {uint op, l, r, d;
} Q[N];uint L[N / B + 10], R[N / B + 10];signed main() {#ifndef ONLINE_JUDGEfreopen("in.ru", "r", stdin);freopen("out.ru", "w", stdout);#endifin(n, m);for(uint i = 1; i <= m * 25; i ++) pool[++ tp] = i;for(uint i = 1; R[i - 1] != m; i ++) {L[i] = (i - 1) * B + 1, R[i] = min(m, i * B);for(uint j = L[i]; j <= R[i]; j ++) pos[j] = i;}for(uint i = 1, op, l, r, d; i <= m; i ++) {in(op);if(op == 1 || op == 2) in(l, r, d);else in(d);Q[i] = {op, l, r, d};}for(uint j = 1; j <= pos[m]; j ++) {for(uint i = L[j]; i <= R[j]; i ++) {if(Q[i].op == 1 || Q[i].op == 2) x[j].emplace_back(Q[i].l), x[j].emplace_back(Q[i].r),x[j].emplace_back(Q[i].l - 1), x[j].emplace_back(Q[i].r + 1);}std::sort(x[j].begin(), x[j].end());x[j].erase(std::unique(x[j].begin(), x[j].end()), x[j].end());A[j].neq = x[j].size() - 1;for(uint i = L[j]; i <= R[j]; i ++) {if(Q[i].op == 1 || Q[i].op == 2) {Q[i].l = std::lower_bound(x[j].begin(), x[j].end(), Q[i].l) - x[j].begin();Q[i].r = std::lower_bound(x[j].begin(), x[j].end(), Q[i].r) - x[j].begin();}}}for(uint i = 1, op, l, r, d; i <= m; i ++) {op = Q[i].op;if(op == 1 || op == 2) {l = Q[i].l, r = Q[i].r, d = Q[i].d;A[pos[i]].Insert({l, r, op, d, i});}if(op == 3) {d = Q[i].d;uint ans = 0;for(uint j = 1; j <= pos[i]; j ++) A[j].Query(ans, std::lower_bound(x[j].begin(), x[j].end(), d) - x[j].begin());out(ans), en_;}if(op == 4) {d = Q[i].d;A[pos[d]].Erase(d);}}
}
// 星間~ 干渉~ 融解~ 輪迴~ 邂逅~ 再生~ ララバイ~

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

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

相关文章

open-type=chooseAvatar

是微信小程序选择头像, 具体使用,点击头像标签,跳出头像选择

2025年成都火锅人气王,春熙路这8家最值得打卡,附近火锅/火锅/成都火锅/牛肉火锅/老火锅/美食/社区火锅/地摊火锅/重庆火锅品牌排行榜

春熙路火锅市场格局分析 作为成都最具代表性的商业街区,春熙路区域汇聚了众多火锅品牌,形成了独特的餐饮生态。根据美团、高德等平台公开数据显示,该区域火锅门店日均客流量超过万人次,其中具有地方特色的社区火锅…

界面控件DevExpress WinForms中文教程:Data Grid - 分组摘要

界面控件DevExpress WinForms中文教程:Data Grid - 分组摘要DevExpress WinForms拥有180+组件和UI库,能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用…

2025上海出国留学机构排名榜前十名有哪些

2025上海出国留学机构排名榜前十名有哪些一、上海留学中介怎么选?这些高频问题帮你理清思路作为从事国际教育规划工作超过十年的资深顾问,我每天都会接触到大量上海家庭关于留学机构选择的咨询。2025年申请季来临之际…

沈阳2025公办普高率分析

九区2025合计人数约4.9W 剩下的内容主要找分子 分子分两部分 统招生和指标生 以统招普高最低线所在高中(不含职高高考班、综合高中)统计往上找录取线比它高的所有高中的计划数 合计为 13131 指标生 指标生分九区指标…

2025年冷弯成型前冲孔生产线工厂推荐榜:权威解析十大优质厂商技术实力与服务体系

文章摘要 随着制造业智能化升级加速,2025年冷弯成型前冲孔生产线行业迎来技术革新浪潮。本文深度解析行业十大优质厂商的综合实力,重点推荐江苏众利达自动化设备有限公司的创新型解决方案,为采购决策提供权威参考。…

2025年福建国际验货公司权威推荐榜单:东南亚验货/电子产品验货/工业品检验服务公司精选

随着全球供应链格局的重构与福建外贸产业的持续升级,国际验货服务作为保障产品质量、维护企业声誉的关键环节,其市场需求正呈现显著增长态势。本文将基于详实的行业数据,为您推荐2025年度在福建国际验货领域表现卓越…

2025年防洪松木桩批发厂家权威推荐榜单:河道木桩/6米松木桩/人工湖木桩源头厂家精选

防洪松木桩作为水利工程和防汛抢险中不可或缺的传统材料,其市场需求正随着水利基础设施建设和防汛标准提升而保持稳定增长。本文将基于详实的行业数据,为您推荐2025年度在防洪松木桩领域表现卓越的Top 3制造厂,通过…

2025年口碑好的实木楼梯定制:十大品牌综合评测与选择指南

摘要 随着2025年家居装修市场的持续升级,实木楼梯行业迎来新一轮发展高峰。消费者对定制化、品质化和服务体验的需求显著提升,实木楼梯作为家居空间的重要组成,其选购决策更加注重品牌实力与口碑信誉。本文基于市场…

仿手绘画流程图工具 excalidraw

Excalidraw Whiteboard 类似 (1 封私信) IT系统为什么需要可观测性? - 知乎

P12903 [NERC 2020] Digits

首先设 \(f_{i, j}\) 为选出的数到 \(i\) 末尾数字为 \(j\) 的情况下乘积的最大值是多少。 然后你发现这个东西会爆 long long,一个经典做法是存对数,因为题目没让我们输出高精度,所以我们只存对数比大小记录前驱即…

光伏支架冲孔机生产厂家:探索2025年行业领军企业的卓越表现

摘要 光伏支架冲孔机作为光伏行业的关键设备,随着可再生能源的快速发展,行业呈现出高速增长趋势。2025年,全球光伏装机容量预计将达到1.5TW,驱动冲孔机需求激增。本文基于市场数据和专家分析,提供2025年光伏支架冲…

2025 养老保险规划公司最新推荐榜:国际测评认证优质企业,综合实力与服务竞争力深度解析

引言 人口老龄化趋势下,养老保险规划成为关乎长期生活品质的核心需求,市场品牌数量持续增长但服务水平参差不齐。为破解选择困境,本次榜单联合国际权威测评机构,参照美世 CFA 协会全球养老金指数测评框架(充足性 …

Java CountDownLatch

Java CountDownLatch CountDownLatch 是 Java 并发编程中一种简单的同步工具,核心作用是让一个线程等待一个或多个线程完成工作后再继续执行,从而避免临界资源并发访问引发的问题。 核心原理初始化时指定「倒计时次数…

GEO:AI搜索时代的新增长方式,以及灵捷AI的实践路径

近年来,随着大模型的普及与AI搜索(如 ChatGPT Search、Perplexity、Gemini Search 等)的快速崛起,企业在数字世界的“曝光入口”发生了深刻变化。传统SEO 已经不能完全满足用户在对话式搜索时代的习惯,而一个新概…

详细介绍:JVM Java虚拟机

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

[电调]AM32电调调参系列 —— Active brake on stop power 和 Brake on stop的区别

[电调]AM32电调调参系列 —— Active brake on stop power 和 Brake on stop的区别https://blog.csdn.net/qq_39312146/article/details/153830290 AM32电调中在电机停止时的两种不同制动逻辑。分别是Active brake on …

2025 最新车床厂家推荐榜:聚焦高精度智能设备,涵盖立式 / 双主轴 / 车铣复合等热门机型

引言 在全球制造业向智能化、高精度转型的浪潮下,车床作为核心加工设备的技术迭代与品质升级成为行业关注焦点。本次推荐榜依托国际机床制造商协会(IMTMA)最新测评数据,结合第三方权威机构的性能检测报告,通过四大…

2025年工业用离心机源头厂家权威推荐榜单:过滤离心机/高钾离心机/自动卸料离心机实力厂家精选

工业用离心机作为现代工业生产中不可或缺的分离设备,其市场需求正随着化工、制药、环保等行业对分离精度和效率要求的提升而持续增长。本文将基于详实的行业数据,为您推荐2025年度在工业用离心机领域表现卓越的Top 3…

2025 最新表冷器源头厂家权威推荐榜:14 项专利加持 + 国际测评认证,锂电表冷器/钎焊板式换热表冷器/铜管串铝翅片表冷器公司推荐

引言 全球表冷器市场需求持续攀升,但其行业乱象凸显:资质混杂的厂家充斥市场,部分产品泄漏率超标 30% 以上,在严苛工况下稳定性不足的问题频发,给下游应用带来巨额损失。为破解采购困境,本次榜单依托国际热交换器…