P6109 Ynoi2009 rprmq1
P6109 Ynoi2009 rprmq1
二区间合并(猫树)妙妙题。
思路
两维问题,可以离线。
直接线段树空间时间都不允许,考虑将一维离线。
如果分块的话每个块维护块内各个位置的最值,散块暴力处理。
考虑将分块的
将第一维加入到猫树上,第二维线段树。
把问题拆分到猫树的区间上。
考虑用线段树处理一次查询,设当前是第
当
但由于我们每次查询的是
将线段树改造为历史和线段树,支持记录一段时间以来每个区间的最值信息。
在
所以线段树要实现这样的功能:
- 历史最值查询及更新
- 历史最值同步当前最值
在 P4314 CPU 监控 有详细介绍,这里不做过多分析。
最后分析复杂度,暴力修改的移动距离在
由于猫树,线段树查询时间复杂度
总复杂度
CODE
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn=5e5+5;
int n,m,id,cur,q,md;
int a[maxn],pos[maxn];
ll ans[maxn];
int cnt;
struct solder{int l,r,tim;}sr[maxn];
struct option{int l,r,v;};
struct qry{int id,l,r;};
vector<option>chg[maxn];
vector<qry>vec[20][maxn];
namespace linetree
{
#define lch(p) p*2
#define rch(p) p*2+1
struct treenode{ll add,hadd,mx,hmx;bool clrtag;}tr[maxn*8];
inline void pushup(int p)
{
tr[p].mx=max(tr[lch(p)].mx,tr[rch(p)].mx);
tr[p].hmx=max(tr[lch(p)].hmx,tr[rch(p)].hmx);
}
inline void pushdown(int p)
{
if(tr[p].clrtag)
{
tr[lch(p)].clrtag=tr[rch(p)].clrtag=1;
tr[lch(p)].hadd=tr[rch(p)].hadd=-1e18;
tr[lch(p)].hmx=tr[rch(p)].hmx=-1e18;
tr[p].clrtag=0;
}
tr[lch(p)].hadd=max({tr[lch(p)].hadd,tr[lch(p)].add+tr[p].hadd});
tr[rch(p)].hadd=max({tr[rch(p)].hadd,tr[rch(p)].add+tr[p].hadd});
tr[lch(p)].hmx=max(tr[lch(p)].hmx,tr[lch(p)].mx+tr[p].hadd);
tr[rch(p)].hmx=max(tr[rch(p)].hmx,tr[rch(p)].mx+tr[p].hadd);
tr[lch(p)].mx+=tr[p].add;tr[rch(p)].mx+=tr[p].add;
tr[lch(p)].add+=tr[p].add;tr[rch(p)].add+=tr[p].add;
tr[p].add=0,tr[p].hadd=0;
}
inline void change(int p,int l,int r,int lx,int rx,int val)
{
if(r<lx||l>rx) return ;
if(lx<=l&&r<=rx)
{
tr[p].add+=val;
tr[p].hadd=max(tr[p].hadd,tr[p].add);
tr[p].mx+=val;
tr[p].hmx=max(tr[p].hmx,tr[p].mx);
return ;
}
pushdown(p);
int mid=(l+r)>>1;
change(lch(p),l,mid,lx,rx,val);change(rch(p),mid+1,r,lx,rx,val);
pushup(p);
}
inline ll qry(int p,int l,int r,int lx,int rx)
{
if(r<lx||l>rx) return -1e18;
if(lx<=l&&r<=rx) return tr[p].hmx;
pushdown(p);
int mid=(l+r)>>1;
return max(qry(lch(p),l,mid,lx,rx),qry(rch(p),mid+1,r,lx,rx));
}
inline void clrtag(){pushdown(1);tr[1].clrtag=1;tr[1].hmx=tr[1].mx;}
}
namespace meowtree
{
#define lch(p) p*2
#define rch(p) p*2+1
inline void build(int p,int l,int r,int dep)
{
md=max(md,dep);
if(l==r){pos[l]=p;return ;}
int mid=(l+r)>>1;
build(lch(p),l,mid,dep+1),build(rch(p),mid+1,r,dep+1);
}
inline void Go(int mid)
{
while(cur<mid)
{
cur++;
for(auto v:chg[cur]) linetree::change(1,1,n,v.l,v.r,v.v);
}
while(cur>mid)
{
for(auto v:chg[cur]) linetree::change(1,1,n,v.l,v.r,-v.v);
cur--;
}
linetree::clrtag();
}
inline void solve(int p,int l,int r,int dep)
{
int mid=(l+r)>>1;
if(l==r)
{
Go(mid);
for(auto v:vec[dep][mid]) ans[v.id]=max(ans[v.id],linetree::qry(1,1,n,v.l,v.r));
return ;
}
Go(mid);
for(int i=mid;i>=l;i--)
{
for(auto v:vec[dep][i]) ans[v.id]=max(ans[v.id],linetree::qry(1,1,n,v.l,v.r));
for(auto v:chg[cur]) if(-v.v<0) linetree::change(1,1,n,v.l,v.r,-v.v);
for(auto v:chg[cur]) if(-v.v>0) linetree::change(1,1,n,v.l,v.r,-v.v);
cur--;
}
Go(mid);
for(int i=mid+1;i<=r;i++)
{
cur++;
for(auto v:chg[cur]) if(v.v<0) linetree::change(1,1,n,v.l,v.r,v.v);
for(auto v:chg[cur]) if(v.v>0) linetree::change(1,1,n,v.l,v.r,v.v);
for(auto v:vec[dep][i]) ans[v.id]=max(ans[v.id],linetree::qry(1,1,n,v.l,v.r));
}
solve(p*2,l,mid,dep+1),solve(p*2+1,mid+1,r,dep+1);
}
}
int main()
{
memset(ans,-0x7f,sizeof(ans));
scanf("%d%d%d",&n,&m,&q);
int len=1;while(len<n) len*=2;
meowtree::build(1,1,len,1);
for(int i=1;i<=m;i++)
{
int lx,rx,ly,ry,x;
scanf("%d%d%d%d%d",&lx,&ly,&rx,&ry,&x);
chg[lx].push_back({ly,ry,x});
chg[rx+1].push_back({ly,ry,-x});
}
for(int i=1;i<=q;i++)
{
int lx,rx,ly,ry;
scanf("%d%d%d%d",&lx,&ly,&rx,&ry);
if(lx==rx){vec[md][lx].push_back({i,ly,ry});continue;}
int dep=(int)log2(pos[lx])-(int)log2(pos[lx]^pos[rx]);
vec[dep][lx].push_back({i,ly,ry});
vec[dep][rx].push_back({i,ly,ry});
}
meowtree::solve(1,1,len,1);
for(int i=1;i<=q;i++) printf("%lld\n",ans[i]);
}
码风优秀,主要部分长度短
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!