文章目录

题目链接:

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);
			}
		}
	}
}