文章目录
题目链接:
https://cn.vjudge.net/problem/UVA-11297
这道题暴力阔以过
原来我以前寒假集训的时候写的是个假的线段树T_T,只有一维是用了线段树,另一维是暴力,原来我一直都没学习到真正的二维线段树,原来上下建的线段树的每一段都要新建个左右的线段树
#include"bits/stdc++.h"
using namespace std;
typedef long long LL;
const int maxn=500+5;
const int MOD=1e9+7;
int N,Q;
int Max[maxn<<2][maxn<<2],Min[maxn<<2][maxn<<2],a[maxn][maxn];
void pushup(int id1,int id2,int cmd)//cmd==1上下更新,cmd==2左右更新
{
if(cmd&1)
{
Max[id1][id2]=max(Max[id1<<1][id2],Max[id1<<1|1][id2]);
Min[id1][id2]=min(Min[id1<<1][id2],Min[id1<<1|1][id2]);
}
if(cmd&(1<<1))
{
Max[id1][id2]=max(Max[id1][id2<<1],Max[id1][id2<<1|1]);
Min[id1][id2]=min(Min[id1][id2<<1],Min[id1][id2<<1|1]);
}
}
void BuildLR(int id1,int id2,int L,int R,int U)//表示在第U行左右建树,如果U==-1,表示有很多行
{
if(L==R)
{
if(U>0)Max[id1][id2]=Min[id1][id2]=a[U][L];
else pushup(id1,id2,1);//上下更新
}
else
{
int mid=L+R>>1;
BuildLR(id1,id2<<1 ,L ,mid,U);
BuildLR(id1,id2<<1|1,mid+1,R,U);
pushup(id1,id2,2);//左右更新
}
}
void BuildUD(int id,int U,int D)//上下建树
{
if(U==D)BuildLR(id,1,1,N,U);
else
{
int mid=U+D>>1;
BuildUD(id<<1 ,U ,mid);
BuildUD(id<<1|1,mid+1,D);
BuildLR(id,1,1,N,-1);//-1表示不只一行也进行左右建树
}
}
void UpdateLR(int id1,int id2,int L,int R,int qL,int qR,int U,int x)
{
if(qL<=L&&qR>=R)
{
if(U>0)Max[id1][id2]=Min[id1][id2]=x;
else pushup(id1,id2,1);
}
else
{
int mid=L+R>>1;
if(qL<=mid)UpdateLR(id1,id2<<1,L,mid,qL,qR,U,x);
if(qR>=mid+1)UpdateLR(id1,id2<<1|1,mid+1,R,qL,qR,U,x);
pushup(id1,id2,2);
}
}
void UpdateUD(int id,int U,int D,int qU,int qD,int qL,int qR,int x)
{
if(U==D)UpdateLR(id,1,1,N,qL,qR,U,x);
else
{
int mid=U+D>>1;
if(qU<=mid)UpdateUD(id<<1,U,mid,qU,qD,qL,qR,x);
if(qD>=mid+1)UpdateUD(id<<1|1,mid+1,D,qU,qD,qL,qR,x);
UpdateLR(id,1,1,N,qL,qR,-1,x);//不止一行的时候进入左右更新
}
}
pair<int,int>queryLR(int id1,int id2,int L,int R,int qL,int qR,int U)
{
if(qL<=L&&qR>=R)return make_pair(Max[id1][id2],Min[id1][id2]);
else
{
int mid=L+R>>1;
pair<int,int>res,tp;
res.first=0,res.second=1e9;
if(qL<=mid)
{
tp=queryLR(id1,id2<<1,L,mid,qL,qR,U);
res.first=max(res.first,tp.first);
res.second=min(res.second,tp.second);
}
if(qR>=mid+1)
{
tp=queryLR(id1,id2<<1|1,mid+1,R,qL,qR,U);
res.first=max(res.first,tp.first);
res.second=min(res.second,tp.second);
}
return res;
}
}
pair<int,int> queryUD(int id,int U,int D,int qU,int qD,int qL,int qR)
{
if(qU<=U&&qD>=D)return queryLR(id,1,1,N,qL,qR,U==D?U:-1);
else
{
int mid=U+D>>1;
pair<int,int>res,tp;
res.first=0,res.second=1e9;
if(qU<=mid)
{
tp=queryUD(id<<1,U,mid,qU,qD,qL,qR);
res.first=max(res.first,tp.first);
res.second=min(res.second,tp.second);
}
if(qD>=mid+1)
{
tp=queryUD(id<<1|1,mid+1,D,qU,qD,qL,qR);
res.first=max(res.first,tp.first);
res.second=min(res.second,tp.second);
}
return res;
}
}
int main()
{
while(cin>>N)
{
for(int i=1;i<=N;i++)for(int j=1;j<=N;j++)scanf("%d",&a[i][j]);
BuildUD(1,1,N);
cin>>Q;
while(Q--)
{
char cmd;
cin>>cmd;
if(cmd=='q')
{
int qU,qD,qL,qR;
scanf("%d%d%d%d",&qU,&qL,&qD,&qR);
pair<int,int>res=queryUD(1,1,N,qU,qD,qL,qR);
cout<<res.first<<" "<<res.second<<endl;
}
else
{
int qU,qL,x;
scanf("%d%d%d%d",&qU,&qL,&x);
UpdateUD(1,1,N,qU,qU,qL,qL,x);
}
}
}
}