现在上真正的二维线段树 毕竟 刚刚那个是卡常 过题我们现在做一个更高级的做法二维线段树。

大体上维护一颗x轴线段树 然后在每个节点的下方再吊一颗维护y轴的线段树那么此时我们整个平面就被我们玩好了。

这样形成二维线段树比刚才的要 合理多了。

写起来 不免有点蒙蔽...然后突然就顿悟了 其实每次我们对于区间的修改大概就是先把x属于x轴的那一段区间给拎出来然后在那个区间之中把那个区间的y轴线段树给修改掉。

还是刚刚那道题 这次是MLE 了 理论上二维线段树空间复杂度 (MAXN<<2)^2这个复杂度 可是正中下怀的MLE了 开小了一点就可以过了。

//#include<bits/stdc++.h>
#include<iostream>
#include<iomanip>
#include<ctime>
#include<cstring>
#include<string>
#include<ctime>
#include<cctype>
#include<cstdio>
#include<utility>
#include<queue>
#include<stack>
#include<deque>
#include<map>
#include<set>
#include<bitset>
#include<vector>
#include<algorithm>
#include<cstdlib>
#define INF 1000000000
#define ll long long
#define mx(p) t[p].mx
#define tag(p) t[p].tag
#define RE register
using namespace std;
char buf[<<],*fs,*ft;
inline char getc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,,<<,stdin),fs==ft))?:*fs++;
}
inline int read()
{
RE int x=,f=;RE char ch=getc();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getc();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getc();}
return x*f;
}
const int MAXN=;
int n,m,Q;
int qx,xx,qy,yy,h;
inline int max(int x,int y){return x>y?x:y;}
struct wy
{
int mx[MAXN],tag[MAXN];
inline void change(int p,int l,int r,int x,int y,int k)
{
mx[p]=max(mx[p],k);
if(l==x&&r==y)
{
tag[p]=max(tag[p],k);
return;
}
int mid=(l+r)>>;
if(y<=mid)change(p<<,l,mid,x,y,k);
else
{
if(x>mid)change(p<<|,mid+,r,x,y,k);
else change(p<<,l,mid,x,mid,k),change(p<<|,mid+,r,mid+,y,k);
}
}
inline int ask(int p,int l,int r,int x,int y)
{
if(l==x&&r==y)return mx[p];
int mid=(l+r)>>,ans=tag[p];
if(y<=mid)ans=max(ans,ask(p<<,l,mid,x,y));
else
{
if(x>mid)ans=max(ans,ask(p<<|,mid+,r,x,y));
else ans=max(ans,max(ask(p<<,l,mid,x,mid),ask(p<<|,mid+,r,mid+,y)));
}
return ans;
}
};
struct tx
{
wy mx[MAXN],tag[MAXN];
inline void change(int p,int l,int r,int x,int y,int k)
{
mx[p].change(,,m,qy,yy,k);
if(l==x&&r==y)
{
tag[p].change(,,m,qy,yy,k);
return;
}
int mid=(l+r)>>;
if(y<=mid)change(p<<,l,mid,x,y,k);
else
{
if(x>mid)change(p<<|,mid+,r,x,y,k);
else change(p<<,l,mid,x,mid,k),change(p<<|,mid+,r,mid+,y,k);
}
}
inline int ask(int p,int l,int r,int x,int y)
{
if(l==x&&r==y)return mx[p].ask(,,m,qy,yy);
int mid=(l+r)>>,ans=tag[p].ask(,,m,qy,yy);
if(y<=mid)ans=max(ans,ask(p<<,l,mid,x,y));
else
{
if(x>mid)ans=max(ans,ask(p<<|,mid+,r,x,y));
else
{
ans=max(ans,ask(p<<,l,mid,x,mid));
ans=max(ans,ask(p<<|,mid+,r,mid+,y));
}
}
return ans;
}
}T;
int main()
{
freopen("1.in","r",stdin);
n=read();m=read();Q=read();
while(Q--)
{
xx=read();yy=read();h=read();
qx=read()+;qy=read()+;
xx=qx+xx-;yy=qy+yy-;
int ans=T.ask(,,n,qx,xx);
T.change(,,n,qx,xx,ans+h);
}
qx=;qy=;xx=n;yy=m;
printf("%d\n",T.ask(,,n,qx,xx));
return ;
}

操作还是不太熟悉 觉得这个可持久化有点神仙没写过有点 怀疑 不过正确性 和 合理性都是比较显然的。

简述一下大体的思路吧 首先对x轴开一棵线段树然后 在x轴的这颗线段树每个节点处都吊着一棵y轴的线段树。

下传修改标记 的时候 对于到过路径上的所有的节点都应该修改值 因为这是标记所致 到了锁定的区间之后标记永久化 对这个tag打上标记 而对内部的y轴线段树也进行一次标记永久化。

通俗的来说 内外线段树处理方式一模一样。为什么不能下传标记 显然的是我们对于外层线段树的修改 在自己的内部是无法下传的 因为标记是无法合并的 比如说 ta 要修改1 n 1 2这个区间ta又要修改1 n 1 3这个区间显然这两个区间在x线段树上是对等的在y线段树上可并不对等所以这两个标记很难合并 故应该标记永久化减少合并的麻烦。

这里我们很完美的解决了 二维线段树的问题。 单次操作时间显然是 logn^2.

二维线段树->树套树的更多相关文章

  1. poj 2155 matrix 二维线段树 线段树套线段树

    题意 一个$n*n$矩阵,初始全为0,每次翻转一个子矩阵,然后单点查找 题解 任意一种能维护二维平面的数据结构都可以 我这里写的是二维线段树,因为四分树的写法复杂度可能会退化,因此考虑用树套树实现二维 ...

  2. BZOJ.4553.[HEOI2016&TJOI2016]序列(DP 树状数组套线段树/二维线段树(MLE) 动态开点)

    题目链接:BZOJ 洛谷 \(O(n^2)\)DP很好写,对于当前的i从之前满足条件的j中选一个最大值,\(dp[i]=d[j]+1\) for(int j=1; j<i; ++j) if(a[ ...

  3. UVA 11297 线段树套线段树(二维线段树)

    题目大意: 就是在二维的空间内进行单个的修改,或者进行整块矩形区域的最大最小值查询 二维线段树树,要注意的是第一维上不是叶子形成的第二维线段树和叶子形成的第二维线段树要  不同的处理方式,非叶子形成的 ...

  4. HDU 4819 Mosaic --二维线段树(树套树)

    题意: 给一个矩阵,每次查询一个子矩阵内的最大最小值,然后更新子矩阵中心点为(Max+Min)/2. 解法: 由于是矩阵,且要求区间最大最小和更新单点,很容易想到二维的线段树,可是因为之前没写过二维的 ...

  5. HDU 1823 Luck and Love 二维线段树(树套树)

    点击打开链接 Luck and Love Time Limit: 10000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Ot ...

  6. 【BZOJ4785】[Zjoi2017]树状数组 树套树(二维线段树)

    [BZOJ4785][Zjoi2017]树状数组 Description 漆黑的晚上,九条可怜躺在床上辗转反侧.难以入眠的她想起了若干年前她的一次悲惨的OI 比赛经历.那是一道基础的树状数组题.给出一 ...

  7. poj 1195:Mobile phones(二维线段树,矩阵求和)

    Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 14391   Accepted: 6685 De ...

  8. HDU 4819 Mosaic(13年长春现场 二维线段树)

    HDU 4819 Mosaic 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4819 题意:给定一个n*n的矩阵,每次给定一个子矩阵区域(x,y,l) ...

  9. 洛谷.3437.[POI2006]TET-Tetris 3D(二维线段树)

    题目链接 下落一个d*s的方块,则要在这个平面区域找一个最高的h' 更新整个平面区域的值为h+h' 对于本题,维护最大高度h和all 对于平面的x轴维护一棵线段树t1,每个t1的节点维护对应y轴的两棵 ...

随机推荐

  1. LESS 原理,一款css的预处理程序Less的使用

    ​Less一种动态样式语言,LESS将CSS赋予了动态语言的特性,如变量,继承,运算,函数...LESS 既可以在客户端上运行 (支持IE 6+, Webkit, Firefox),也可以借助Node ...

  2. JavaScript图形实例:Hilbert曲线

    德国数学家David Hilbert在1891年构造了一种曲线,首先把一个正方形等分成四个小正方形,依次从西北角的正方形中心出发往南到西南正方形中心,再往东到东南角的正方形中心,再往北到东北角正方形中 ...

  3. 【Python】__name__ 是什么?

    前言 在我们浏览一下 python 文件或者自己写 python 代码的时候,时常会在代码的最后加上这样的一行代码 if __name__ == '__main__': func_name() 那么这 ...

  4. Windows下生成IOS证书并发布APP安装到IPhone

    目录: 一:生成证书 二:安装到IPhone 准备环境: 1.Appuploader(需要安装Java环境) 2.爱思助手 一.生成证书 1.1.打开appuploader后登陆开发者账号 1.2.点 ...

  5. 主题博客添加 h5 贴边音乐插件

    前言: 前几日,在逛微博的时候,发现微博主页的左下角有一个贴边的音乐小插件,我顿时就想在自己博客上也弄一个玩玩.当时就想把微博那个移植过来,首先我用谷歌浏览器F12 查看页面源码,和检查元素代码,发现 ...

  6. scala 数据结构(四):列表 List

    1 列表 List-创建List 基本介绍 Scala中的List 和Java List 不一样,在Java中List是一个接口,真正存放数据是ArrayList,而Scala的List可以直接存放数 ...

  7. java 基本语法(十九)Optional类的使用

    java.util.Optional类1.理解:为了解决java中的空指针问题而生!Optional<T> 类(java.util.Optional) 是一个容器类,它可以保存类型T的值, ...

  8. 机器学习实战基础(十五):sklearn中的数据预处理和特征工程(八)特征选择 之 Filter过滤法(二) 相关性过滤

    相关性过滤 方差挑选完毕之后,我们就要考虑下一个问题:相关性了. 我们希望选出与标签相关且有意义的特征,因为这样的特征能够为我们提供大量信息.如果特征与标签无关,那只会白白浪费我们的计算内存,可能还会 ...

  9. python并发编程02 /多进程、进程的创建、进程PID、join方法、进程对象属性、守护进程

    python并发编程02 /多进程.进程的创建.进程PID.join方法.进程对象属性.守护进程 目录 python并发编程02 /多进程.进程的创建.进程PID.join方法.进程对象属性.守护进程 ...

  10. 在Java中使用AES加密

    本文转载https://blog.csdn.net/z69183787/article/details/82746686