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

大体上维护一颗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. (二)LVS介绍

    LVS分3种模式  (a)NAT(网络地址映射):通过网络地址转换的方法来实现调度       优点:支持所有操作系统及私有网络,且只需一个公网 IP 地址       缺点:用户请求和响应报文都必须 ...

  2. 07 Vue常见插件

    项目功能插件 1.vue-router { path: '/', name: 'home', // 路由的重定向 redirect: '/home' } { // 一级路由, 在根组件中被渲染, 替换 ...

  3. python 将指定文件夹中的指定文件放入指定文件夹中

    import os import shutil import re #获取指定文件中文件名 def get_filename(filetype): name =[] final_name_list = ...

  4. python eval函数,将列表样式的字符串转化为列表

    python eval函数,将列表样式的字符串转化为列表 >>> str_1 = '[1,2,3,4,5,6]'>>> type(str_1)<type 's ...

  5. flask 源码专题(九):flask扩展点

    1. 信号(源码) 信号,是在flask框架中为我们预留的钩子,让我们可以进行一些自定义操作. pip3 install blinker 2. 根据flask项目的请求流程来进行设置扩展点 中间件 # ...

  6. redis(三):Redis 命令(python)

    import redis from redis import StrictRedis redis=StrictRedis(host='localhost',port=6379,db=0,passwor ...

  7. Python函数07/有参装饰器/多个装饰器装饰一个函数

    Python函数07/有参装饰器/多个装饰器装饰一个函数 目录 Python函数07/有参装饰器/多个装饰器装饰一个函数 内容大纲 1.有参装饰器 2.多个装饰器装饰一个函数 3.今日总结 3.今日练 ...

  8. 史上最强vue总结~万字长文---面试开发全靠它了

    vue框架篇 vue的优点 轻量级框架:只关注视图层,是一个构建数据的视图集合,大小只有几十kb: 简单易学:国人开发,中文文档,不存在语言障碍 ,易于理解和学习: 双向数据绑定:保留了angular ...

  9. (2)简单理解和使用webpack-dev-server

    webpack-dev-server能做什么? 每次打包都得像之前一样使用webapck 入口文件 -o 出口文件,每次修改都得打包一次过于麻烦,可以使用webpack-dev-server实现自动打 ...

  10. Babel:下一代Javascript语法编译器

    定义 Babel是一个Javascript的编译器,通过它你可以将一些新版本的ECMAScript语法转换成低版本的语法.以便能够在低版本的浏览器或者其它环境平稳运行. 截至目前笔者写这篇文章的时候, ...