[UVa11297]Census:树套树/二维线段树/线段树套线段树

二维线段树的裸题,据说用四叉树也可以做。
因为每个区域都有值所以使用了静态开点。
代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <utility>
using namespace std;
typedef long long LL;
typedef pair<LL,LL> Pll;
const int MAXN=505;
const LL INF=0x3f3f3f3f3f3f3f3f;
inline LL read(){
    LL x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
    return x*f;
}
int n,ql,qr,qu,qd,locx,locy;
LL a[MAXN][MAXN],k;Pll t[MAXN<<2][MAXN<<2];
Pll merge(Pll x,Pll y){
    Pll ans;
    ans.first=max(x.first,y.first);
    ans.second=min(x.second,y.second);
    return ans;
}
#define mid ((l+r)>>1)
#define lc (o<<1)
#define rc ((o<<1)|1)
void updy(int o,int l,int r,int preo,int typ){
    if(l==r&&l==locy){
        if(typ){
            t[preo][o].first=t[preo][o].second=k;
            return;
        }
        t[preo][o]=merge(t[preo<<1][o],t[(preo<<1)|1][o]);
        return;
    }
    if(locy<=mid) updy(lc,l,mid,preo,typ);
    else updy(rc,mid+1,r,preo,typ);
    t[preo][o]=merge(t[preo][lc],t[preo][rc]);
}
Pll queryy(int o,int l,int r,int preo){
    if(ql<=l&&r<=qr) return t[preo][o];
    Pll ans;ans.first=-INF,ans.second=INF;
    if(mid>=ql) ans=merge(ans,queryy(lc,l,mid,preo));
    if(mid<qr) ans=merge(ans,queryy(rc,mid+1,r,preo));
    return ans;
}
#undef mid
#define mid ((u+d)>>1)
void updx(int o,int u,int d){
    if(u==d&&u==locx){
        updy(1,1,n,o,1);
        return;
    }
    if(locx<=mid) updx(lc,u,mid);
    else updx(rc,mid+1,d);
    updy(1,1,n,o,0);
}
Pll queryx(int o,int u,int d){
    if(qu<=u&&d<=qd) return queryy(1,1,n,o);
    Pll ans;ans.first=-INF,ans.second=INF;
    if(mid>=qu) ans=merge(ans,queryx(lc,u,mid));
    if(mid<qd) ans=merge(ans,queryx(rc,mid+1,d));
    return ans;
}
#undef mid
#undef lc
#undef rc
int main(){
    n=read();
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            a[i][j]=read();
            locx=i,locy=j,k=a[i][j];
            updx(1,1,n);
        }
    int m=read();
    while(m--){
        char opt;
        scanf("%c",&opt);
        if(opt=='q'){
            qu=read(),ql=read(),qd=read(),qr=read();
            Pll ans=queryx(1,1,n);
            printf("%lld %lld\n",ans.first,ans.second);
        }
        else{
            locx=read(),locy=read(),k=read();
            updx(1,1,n);
        }
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/ErkkiErkko/p/9319939.html