#include <bits/stdc++.h> using namespace std; typedef long long ll; #define ls (o<<1) #define rs (o<<1|1) const int M = 8e3+7; int n; ll c[M][M]; ll tr[M][M]; void up2(int o,int l,int r,int hx,int lx,ll w,int k){ if(l==r){ tr[k][o]=max(w,tr[k][o]); return ; } int m=(l+r)/2; if(lx<=m)up2(ls,l,m,hx,lx,w,k); else up2(rs,m+1,r,hx,lx,w,k); tr[k][o]=max(tr[k][ls],tr[k][rs]); } void up(int o,int l,int r,int hx,int lx,ll w){ up2(1,1,n,hx,lx,w,o); if(l==r)return ; int m=(l+r)/2; if(hx<=m)up(ls,l,m,hx,lx,w); else up(rs,m+1,r,hx,lx,w); } ll tp; void qu2(int o,int l,int r,int lx,int ly,int k){ if(lx<=l&&r<=ly){ tp=max(tp,tr[k][o]); return ; } int m=(l+r)/2; if(lx<=m)qu2(ls,l,m,lx,ly,k); if(ly>m)qu2(rs,m+1,r,lx,ly,k); } void qu(int o,int l,int r,int hx,int hy,int lx,int ly){ if(hx<=l&&r<=hy){ qu2(1,1,n,lx,ly,o); return; } int m=(l+r)/2; if(hx<=m)qu(ls,l,m,hx,hy,lx,ly); if(hy>m)qu(rs,m+1,r,hx,hy,lx,ly); } int main(){ int m1,m2; scanf("%d%d%d",&n,&m1,&m2); for(int i=1;i<=m1;i++){ int hx,hy,lx,ly; ll w; scanf("%d%d%d%d%lld",&hx,&lx,&hy,&ly,&w); c[hy+1][ly+1]+=w,c[hx][ly+1]-=w,c[hy+1][lx]-=w,c[hx][lx]+=w; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) c[i][j]=c[i-1][j]+c[i][j-1]-c[i-1][j-1]+c[i][j],up(1,1,n,i,j,c[i][j]); for(int i=1;i<=m2;i++){ int hx,hy,lx,ly; tp=0; scanf("%d%d%d%d",&hx,&lx,&hy,&ly); qu(1,1,n,hx,hy,lx,ly); printf("%lld ",tp); } }
下面的版本是动态开点的树套树,但是本题卡空间
#include <bits/stdc++.h> using namespace std; typedef long long ll; #define ls (o<<1) #define rs (o<<1|1) const int M = 8e5+7; int n; ll c[2005][2005]; struct Node{ int lson,rson; ll w; }in[15000000]; int tr[M]; int cnt; void up2(int &k,int l,int r,int hx,int lx,ll w){ if(!k)k=++cnt; in[k].w=max(in[k].w,w); if(l==r)return; int m=l+r>>1; if(lx<=m)up2(in[k].lson,l,m,hx,lx,w); else up2(in[k].rson,m+1,r,hx,lx,w); } void up(int o,int l,int r,int hx,int lx,ll w){ up2(tr[o],1,n,hx,lx,w); if(l==r)return ; int m=(l+r)/2; if(hx<=m)up(ls,l,m,hx,lx,w); else up(rs,m+1,r,hx,lx,w); } ll tp; void qu2(int k,int l,int r,int lx,int ly){ if(!k)return; if(lx<=l && ly>=r){tp=max(tp,in[k].w);return;} int m=l+r>>1; if(lx<=m)qu2(in[k].lson,l,m,lx,ly); if(ly>m)qu2(in[k].rson,m+1,r,lx,ly); } void qu(int o,int l,int r,int hx,int hy,int lx,int ly){ if(hx<=l&&r<=hy){ qu2(tr[o],1,n,lx,ly); return; } int m=(l+r)/2; if(hx<=m)qu(ls,l,m,hx,hy,lx,ly); if(hy>m)qu(rs,m+1,r,hx,hy,lx,ly); } int main(){ int m1,m2; scanf("%d%d%d",&n,&m1,&m2); for(int i=1;i<=m1;i++){ int hx,hy,lx,ly; ll w; scanf("%d%d%d%d%lld",&hx,&lx,&hy,&ly,&w); c[hy+1][ly+1]+=w,c[hx][ly+1]-=w,c[hy+1][lx]-=w,c[hx][lx]+=w; } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) c[i][j]=c[i-1][j]+c[i][j-1]-c[i-1][j-1]+c[i][j],up(1,1,n,i,j,c[i][j]); for(int i=1;i<=m2;i++){ int hx,hy,lx,ly; tp=0; scanf("%d%d%d%d",&hx,&lx,&hy,&ly); qu(1,1,n,hx,hy,lx,ly); printf("%lld ",tp); } } /* 2000 5 5 1 1 4 5 4 4 1 4 1 10 1 3 3 3 3 1 1 5 5 8 2 4 4 5 8 2 1 2 1 4 1 5 4 1 2 3 5 2 1 5 3 1 3 5 5 */