题目

区间加,区间乘,单点查询,撤销修改


分析

由于可以离线,不妨把下标看成第一维,时间看成第二维,那么修改操作相当于在一个矩形上加或者乘,

不妨把查询的节点看作是二维平面上的点,这样实际上就可以用 KD-Tree 来实现


代码

#include <cstdio>
#include <cctype>
#include <algorithm>
using namespace std;
const int N=150011,mod=998244353;
int ran,n,m,Q,root,ans[N];
struct rec{
int p[2];
bool operator <(const rec &t)const{
return p[ran]<t.p[ran];
}
};
struct Rec{int l,r,z,opt,ed;}q[N];
int mo(int x,int y){return x+y>=mod?x+y-mod:x+y;}
void Min(int &x,int y){x=x<y?x:y;}
void Max(int &x,int y){x=x>y?x:y;}
struct KD_Tree{
int mn[N][2],mx[N][2],son[N][2],lazy[N],w[N],tag[N]; rec p[N];
void pup(int now){
mn[now][0]=mx[now][0]=p[now].p[0];
mn[now][1]=mx[now][1]=p[now].p[1];
if (son[now][0]){
Min(mn[now][0],mn[son[now][0]][0]);
Min(mn[now][1],mn[son[now][0]][1]);
Max(mx[now][0],mx[son[now][0]][0]);
Max(mx[now][1],mx[son[now][0]][1]);
}
if (son[now][1]){
Min(mn[now][0],mn[son[now][1]][0]);
Min(mn[now][1],mn[son[now][1]][1]);
Max(mx[now][0],mx[son[now][1]][0]);
Max(mx[now][1],mx[son[now][1]][1]);
}
}
int build(int l,int r,int Ran){
if (l>r) return 0;
int mid=(l+r)>>1;
ran=Ran,nth_element(p+l,p+mid,p+1+r);
son[mid][0]=build(l,mid-1,Ran^1);
son[mid][1]=build(mid+1,r,Ran^1);
tag[mid]=1,pup(mid);
return mid;
}
void ptag(int now,int Tag,int Lazy){
w[now]=mo(1ll*w[now]*Tag%mod,Lazy);
tag[now]=1ll*tag[now]*Tag%mod;
lazy[now]=mo(1ll*lazy[now]*Tag%mod,Lazy);
}
void pdown(int now){
if (son[now][0]) ptag(son[now][0],tag[now],lazy[now]);
if (son[now][1]) ptag(son[now][1],tag[now],lazy[now]);
tag[now]=1,lazy[now]=0;
}
void update(int now,int lx,int rx,int ly,int ry,int opt,int z){
if (mx[now][0]<lx||rx<mn[now][0]||mx[now][1]<ly||ry<mn[now][1]) return;
if (lx<=mn[now][0]&&mx[now][0]<=rx&&ly<=mn[now][1]&&mx[now][1]<=ry){
if (opt==1) ptag(now,1,z);
else ptag(now,z,0);
return;
}
if (lx<=p[now].p[0]&&p[now].p[0]<=rx&&ly<=p[now].p[1]&&p[now].p[1]<=ry){
if (opt==1) w[now]=mo(w[now],z);
else w[now]=1ll*w[now]*z%mod;
}
if (tag[now]!=1||lazy[now]) pdown(now);
if (son[now][0]) update(son[now][0],lx,rx,ly,ry,opt,z);
if (son[now][1]) update(son[now][1],lx,rx,ly,ry,opt,z);
}
void query(int now){
ans[p[now].p[1]]=w[now];
if (tag[now]!=1||lazy[now]) pdown(now);
if (son[now][0]) query(son[now][0]);
if (son[now][1]) query(son[now][1]);
}
}Tre;
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
int main(){
n=iut(),Q=iut();
for (int i=1;i<=Q;++i){
int opt=iut();
if (opt<3){
int l=iut(),r=iut(),z=iut();
if (z>=mod) z-=mod;
q[i]=(Rec){l,r,z,opt,Q};
}else{
int x=iut();
if (opt==3) Tre.p[++m].p[0]=x,Tre.p[m].p[1]=i;
else q[x].ed=i-1,q[i].opt=-1;
}
}
root=Tre.build(1,m,0);
for (int i=1;i<=Q;++i) if (q[i].opt>0)
Tre.update(root,q[i].l,q[i].r,i,q[i].ed,q[i].opt,q[i].z);
Tre.query(root);
for (int i=1;i<=Q;++i) if (!q[i].opt)
print(ans[i]),putchar(10);
return 0;
}

#KD-Tree#洛谷 3710 方方方的数据结构的更多相关文章

  1. 题解 洛谷 P3710 【方方方的数据结构】

    因为有撤销操作,所以修改操作可能会只会存在一段时间,因此把时间看作一维,被修改的序列看作一维. 可以把操作都离线下来,对于每个修改操作,就是在二维平面上对一个矩形进行修改,询问操作,就是查询单点权值. ...

  2. AC日记——【模板】Link Cut Tree 洛谷 P3690

    [模板]Link Cut Tree 思路: LCT模板: 代码: #include <bits/stdc++.h> using namespace std; #define maxn 30 ...

  3. POJ1471 Tree/洛谷P4178 Tree

    Tree P4178 Tree 点分治板子. 点分治就是直接找树的重心进行暴力计算,每次树的深度不会超过子树深度的\(\frac{1}{2}\),计算完就消除影响,找下一个重心. 所以伪代码: voi ...

  4. 洛谷试炼场 提高模板-nlogn数据结构

    树状数组-区间求和 P3374 [模板]树状数组 1 /*by SilverN*/ #include<algorithm> #include<iostream> #includ ...

  5. 洛谷4月月赛R2

    洛谷4月月赛R2 打酱油... A.koishi的数学题  线性筛约数和就可以\(O(N)\)了... #include <iostream> #include <cstdio> ...

  6. 【BZOJ-2648&2716】SJY摆棋子&天使玩偶 KD Tree

    2648: SJY摆棋子 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 2459  Solved: 834[Submit][Status][Discu ...

  7. 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

  8. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  9. 洛谷SP16580 QTREE7 - Query on a tree VII(LCT,multiset)

    洛谷题目传送门 思路分析 维护子树最值还是第一次写QwQ 因为子树的最值会变化,所以不能简单地把最值记下来,还要维护一个平衡树,把每个子树的最大值扔进去,来资磁插入.删除和查询最值. 然后我就懒得手写 ...

  10. 洛谷P2633 Count on a tree(主席树上树)

    题目描述 给定一棵N个节点的树,每个点有一个权值,对于M个询问(u,v,k),你需要回答u xor lastans和v这两个节点间第K小的点权.其中lastans是上一个询问的答案,初始为0,即第一个 ...

随机推荐

  1. RAID 10磁盘阵列实践

    RAID概述 RAID技术通过把多个硬盘设备组合成一个容量更大.安全性更好的磁盘阵列,利用分散读写技术来提升磁盘阵列整体的性能,同时把多个重要数据的副本同步到不同的物理硬盘设备上,从而起到了非常好的数 ...

  2. goroutine并发

    每一个并非的执行单元叫作一个goroutine.设想这里的一个程序有两个函数,一个函数做计算,另一个输出结果,假设两个函数没有相互之间的调用关系.一个线性的程序会先调用其中的一个函数,然后再调用另一个 ...

  3. 开源软件CVE_Search的配置与使用(详细)

    目录 项目介绍 环境配置 初始化cve_search 使用cve_search 简介 CVE: https://baike.baidu.com/item/CVE/9483464?fr=aladdin ...

  4. 大众点评cat报警源码

    类时序 时许说明 判断是否是报警机器. 1分钟启动一个线程根据设置的报警条件,时间段去查询CAT报告数据. 根据返回的报告数据,逐层解析TYPE,NAME,RANGE中的数据是否满足报警条件. 只有全 ...

  5. 【Azure Function App】本地运行的Function发布到Azure上无法运行的错误分析

    问题描述 Azure Function部署后未执行,查看日志发现错误信息: 2023-12-19T11:12:27.145 [Verbose] Host configuration applied.2 ...

  6. MK5 机械键盘 说明书

    FN + 右箭头 就是加快节奏 FN + ScrLk 就是切换模式

  7. Nginx 同时支持 http 和 https SSL 为了能有权限调取摄像头

    Nginx 同时支持 http 和 https 当然起项目的会后也分成俩 "dev": "vue-cli-service serve --port=8080", ...

  8. docsify + GitHub Page免费搭建个人博客

    docsify生成文档 docsify是一个动态生成文档网站的工具.通过编辑MarkDown文件就能实现简约清爽的文档页面. 先在Github创建项目 创建项目成功后,把项目克隆到本地(以自己的实际地 ...

  9. C#获取Description特性的扩展类

    C#中Description特性主要用于枚举和属性,方法比较简单,记录一下以便后期使用. 扩展类DescriptionExtension代码如下: using System; using System ...

  10. manjaro/archLinux出现什么的签名未知信任的时候

    sudo pacman -S archlinuxcn-keyring 在进行该做的就可以了 出现这种状况的原因是没有规范的更新系统!