#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<queue>
#include<stack>
#include<string>
#include<cstring>
#include<map>
#include<vector>
#include<set>
#include<ctime>
#include<stdlib.h>
using namespace std;
const int mod=99999997;
const double eps=1e-8;
const double pi=acos(-1.0);
const int inf=0x3fffffff;
const int mmax=510;
typedef long long LL;
struct node
{
int l1,r1,l2,r2;
int sum,max_val,min_val;
int mid1()
{
return (l1+r1)>>1;
}
int mid2()
{
return (l2+r2)>>1;
}
}T[4*mmax][4*mmax];
int a[mmax][mmax];
void push_up1D(int id1,int id2)
{
T[id1][id2].l2=T[id1<<1][id2].l2,T[id1][id2].r2=T[id1<<1][id2].r2;
T[id1][id2].sum=T[id1<<1][id2].sum+T[id1<<1|1][id2].sum;
T[id1][id2].max_val=max(T[id1<<1][id2].max_val,T[id1<<1|1][id2].max_val);
T[id1][id2].min_val=min(T[id1<<1][id2].min_val,T[id1<<1|1][id2].min_val);
if(T[id1][id2].l2==T[id1][id2].r2)
return ;
push_up1D(id1,id2<<1);
push_up1D(id1,id2<<1|1);
}
void push_up2D(node &T,node &Tl,node &Tr)
{
T.sum=Tl.sum+Tr.sum;
T.max_val=max(Tl.max_val,Tr.max_val);
T.min_val=min(Tl.min_val,Tr.min_val);
}
void build2D(int id1,int id,int l,int r)
{
T[id1][id].l2=l,T[id1][id].r2=r;
if(l==r)
{
T[id1][id].sum=T[id1][id].max_val=T[id1][id].min_val=a[T[id1][1].l1][l];
return ;
}
int mid=T[id1][id].mid2();
build2D(id1,id<<1,l,mid);
build2D(id1,id<<1|1,mid+1,r);
push_up2D(T[id1][id],T[id1][id<<1],T[id1][id<<1|1]);
}
void build1D(int id,int l,int r,int m)
{
T[id][1].l1=l,T[id][1].r1=r;
if(l==r)
{
build2D(id,1,1,m);
return ;
}
int mid=T[id][1].mid1();
build1D(id<<1,l,mid,m);
build1D(id<<1|1,mid+1,r,m);
push_up1D(id,1);
}
node query2D(int id1,int id,int l,int r)
{
if(l<=T[id1][id].l2&&T[id1][id].r2<=r)
return T[id1][id];
int mid=T[id1][id].mid2();
//cout<<T[id1][id].l2<<" "<<T[id1][id].r2<<endl;
node tmp[3];
int t=0;
if(mid>=l)
tmp[1]=query2D(id1,id<<1,l,r),t++;
if(mid<r)
tmp[2]=query2D(id1,id<<1|1,l,r),t+=2;
if(t<3)
return tmp[t];
push_up2D(tmp[0],tmp[1],tmp[2]);
return tmp[0];
}
node query1D(int id,int l1,int r1,int l2,int r2)
{
if(l1<=T[id][1].l1&&T[id][1].r1<=r1)
return query2D(id,1,l2,r2);
int mid=T[id][1].mid1();
node tmp[3];
int t=0;
if(mid>=l1)
tmp[1]=query1D(id<<1,l1,r1,l2,r2),t++;
if(mid<r1)
tmp[2]=query1D(id<<1|1,l1,r1,l2,r2),t+=2;
if(t<3)
return tmp[t];
push_up2D(tmp[0],tmp[1],tmp[2]);
return tmp[0];
}
void updata2D(int id1,int id,int pos,int val)
{
if(T[id1][id].l2==T[id1][id].r2)
{
T[id1][id].sum=T[id1][id].max_val=T[id1][id].min_val=val;
return ;
}
int mid=T[id1][id].mid2();
if(mid>=pos)
updata2D(id1,id<<1,pos,val);
else
updata2D(id1,id<<1|1,pos,val);
push_up2D(T[id1][id],T[id1][id<<1],T[id1][id<<1|1]);
}
void updata1D(int id,int posx,int posy,int val)
{
if(T[id][1].l1==T[id][1].r1)
{
updata2D(id,1,posy,val);
return ;
}
int mid=T[id][1].mid1();
if(mid>=posx)
updata1D(id<<1,posx,posy,val);
else
updata1D(id<<1|1,posx,posy,val);
push_up1D(id,1);
}
int main()
{
//freopen("in.txt","r",stdin);
int n,m,q;
cin>>n>>m;
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
build1D(1,1,n,m);
cin>>q;
while(q--)
{
int X1,X2,Y1,Y2;
char ch[2];
scanf("%s",ch);
if(ch[0]=='q')
{
scanf("%d %d %d %d",&X1,&Y1,&X2,&Y2);
node ans=query1D(1,X1,X2,Y1,Y2);
printf("%d %d\n",ans.max_val,ans.min_val);
}
if(ch[0]=='c')
{
int V;
scanf("%d %d %d",&X1,&Y1,&V);
updata1D(1,X1,Y1,V);
}
}
return 0;
}
2维线段树
最新推荐文章于 2022-01-26 23:18:59 发布