码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 11297 Census ——二维线段树

时间:2017-01-23 20:15:06      阅读:158      评论:0      收藏:0      [点我收藏+]

标签:oid   mod   min   out   --   push   线段树   stdout   复杂度   

【题目分析】

    二维线段树模板题目。

    简直就是无比的暴力。时间复杂度为两个log。

    标记的更新方式比较奇特,空间复杂度为N^2。

    模板题目。

【代码】

#include <cstdio>
#include <cstring>
//#include <cmath>
#include <cstdlib>
 
#include <map>
#include <set>
#include <queue>
#include <string>
#include <iostream>
#include <algorithm>
 
using namespace std;

#define maxn 505
#define inf 0x3f3f3f3f
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
 
void Finout()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
//    freopen("out.txt","w",stdout);
    #endif
}
 
int Getint()
{
    int 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*10+ch-‘0‘; ch=getchar();}
    return x*f;
}

int mx[maxn<<2][maxn<<2],mn[maxn<<2][maxn<<2],rt[maxn<<2],ma[maxn][maxn],n;
int x,y,c,tot=0,x1,x2,y1,y2;

void pushup(int rt,int o)
{
	mx[rt][o]=max(mx[rt][o<<1],mx[rt][o<<1|1]);
	mn[rt][o]=min(mn[rt][o<<1],mn[rt][o<<1|1]);
}

void update(int rt,int o,int l,int r)
{
//	printf("update %d %d %d %d\n",rt,o,l,r);
	if (l==r)
	{
		mx[rt][o]=max(mx[rt<<1][o],mx[rt<<1|1][o]);
		mn[rt][o]=min(mn[rt<<1][o],mn[rt<<1|1][o]);
		return;
	}
	int mid=l+r>>1;
	if (y<=mid) update(rt,o<<1,l,mid);
	else update(rt,o<<1|1,mid+1,r);
	pushup(rt,o);
}

void push(int rt,int o,int l,int r)
{
	if (l==r)
	{
		mx[rt][o]=mn[rt][o]=c;
		return ;
	}
	int mid=l+r>>1;
	if (y<=mid) push(rt,o<<1,l,mid);
	else push(rt,o<<1|1,mid+1,r);
	pushup(rt,o);
}

void modi(int o,int l,int r)
{
	if (l==r){push(o,1,1,n);return;}
	int mid=l+r>>1;
	if (x<=mid) modi(o<<1,l,mid);
	else modi(o<<1|1,mid+1,r);
	update(o,1,1,n);
}

char opt[11];int amx,amn,q;

void queryy(int rt,int o,int l,int r)
{
//	printf("queryy %d %d %d %d\n",rt,o,l,r);
	if (y1<=l&&r<=y2)
	{
		amx=max(amx,mx[rt][o]);
		amn=min(amn,mn[rt][o]);
		return ;
	}
	int mid=l+r>>1;
	if (y1<=mid) queryy(rt,o<<1,l,mid);
	if (y2>mid) queryy(rt,o<<1|1,mid+1,r);
}

void queryx(int o,int l,int r)
{
//	printf("query x %d %d %d\n",o,l,r);
	if (x1<=l&&r<=x2){ return queryy(o,1,1,n); }
	int mid=l+r>>1;
	if (x1<=mid) queryx(o<<1,l,mid);
	if (x2>mid)  queryx(o<<1|1,mid+1,r);
}

int main()
{
	memset(mx,-0x3f,sizeof mx);
	memset(mn, 0x3f,sizeof mn);
	Finout();
	n=Getint();
	F(i,1,n) F(j,1,n)
	{
		x=i;y=j;
		c=ma[i][j]=Getint();
		modi(1,1,n);
	}
//	cout<<mx[1][1]<<" "<<mn[1][1]<<endl;
	q=Getint();
	F(i,1,q)
	{
		scanf("%s",opt);
		if (opt[0]==‘c‘)
		{
			x=Getint(); y=Getint(); c=Getint();
			modi(1,1,n);
		}
		else
		{
			x1=Getint(); y1=Getint(); x2=Getint(); y2=Getint();
			amx=-inf,amn=inf;
			queryx(1,1,n);
			printf("%d %d\n",amx,amn);
		}
	}
}

  

UVA 11297 Census ——二维线段树

标签:oid   mod   min   out   --   push   线段树   stdout   复杂度   

原文地址:http://www.cnblogs.com/Muliphein/p/6344765.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!