Uva 11297 Census 二维线段树

题目链接:点击打开链接

好久没发题解了,

第一维的线段树更新到底,叶子节点建一棵线段树。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<algorithm>
using namespace std;
template <class T>
inline bool rd(T &ret) {
	char c; int sgn;
	if (c = getchar(), c == EOF) return 0;
	while (c != '-' && (c<'0' || c>'9')) c = getchar();
	sgn = (c == '-') ? -1 : 1;
	ret = (c == '-') ? 0 : (c - '0');
	while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');
	ret *= sgn;
	return 1;
}
template <class T>
inline void pt(T x) {
	if (x <0) {
		putchar('-');
		x = -x;
	}
	if (x>9) pt(x / 10);
	putchar(x % 10 + '0');
}
const int N = 550;
const int inf = 1000 * 1000 * 1000;
int a[N][N];
class Segment_Tree{
public:
	class Node{
	public:
		int l, r, max, min, lazy;
		Node(){}
		Node(int ll, int rr, int mmax, int mmin){
			l = ll; r = rr; max = mmax; min = mmin;
			lazy = inf;
		}
	};
	Node t[N << 2];
	int pos = 0, Max, Min;
	int L(int x){ return x << 1; }
	int R(int x){ return x << 1 | 1; }
	void up(int id){
		t[id].max = max(t[L(id)].max, t[R(id)].max);
		t[id].min = min(t[L(id)].min, t[R(id)].min);
		t[id].lazy = inf;
	}
	void down(int id){
		if (t[id].lazy != inf){
			t[L(id)].max = t[R(id)].max = t[id].lazy;
			t[L(id)].min = t[R(id)].min = t[id].lazy;
			t[L(id)].lazy = t[R(id)].lazy = t[id].lazy;
			t[id].lazy = inf;
		}
	}
	void build(int l, int r, int id){
		t[id] = Node(l, r, 0, 0);
		if (l == r){
			t[id].min = t[id].max = a[pos][l];
			return;
		}
		int mid = (l + r) >> 1;
		build(l, mid, L(id)); build(mid + 1, r, R(id));
		up(id);
	}
	void update(int l, int r, int val, int id){
		if (l == t[id].l && r == t[id].r){
			t[id].max = t[id].min = t[id].lazy = val;
			return;
		}
		down(id);
		int mid = (t[id].l + t[id].r) >> 1;
		if (r <= mid)
			update(l, r, val, L(id));
		else if (mid < l)
			update(l, r, val, R(id));
		else{
			update(l, mid, val, L(id));
			update(mid + 1, r, val, R(id));
		}
		up(id);
	}
	void query(int l, int r, int id){
		if (l == t[id].l && r == t[id].r){
			Min = min(Min, t[id].min);
			Max = max(Max, t[id].max);
			return;
		}
		down(id);
		int mid = (t[id].l + t[id].r) >> 1;
		if (r <= mid)
			query(l, r, L(id));
		else if (mid < l)
			query(l, r, R(id));
		else{
			query(l, mid, L(id));
			query(mid + 1, r, R(id));
		}
	}
	void Q(int l, int r){
		Max = -inf; Min = inf;
		query(l, r, 1);
	}
	void P(int l, int r, int val){
		update(l, r, val, 1);
	}
};
class Two_Dimension_Segment_Tree{
public:
	class Node{
	public:
		int l, r;
		Node(){}
		Node(int ll, int rr){
			l = ll; r = rr;
		}
	};
	Node t[N << 2];
	Segment_Tree T[N];
	int Max, Min, M;
	int L(int x){ return x << 1; }
	int R(int x){ return x << 1 | 1; }

	void build(int l, int r, int id){
		t[id] = Node(l, r);
		if (l == r){
			T[l].pos = l;
			T[l].build(1, M, 1);
			return;
		}
		int mid = (l + r) >> 1;
		build(l, mid, L(id)); build(mid + 1, r, R(id));
	}
	void update(int l, int r, int x, int y, int val, int id){
		if (l == r){
			T[l].P(x, y, val);
			return;
		}
		int mid = (t[id].l + t[id].r) >> 1;
		if (r <= mid)
			update(l, r, x, y, val, L(id));
		else if (mid < l)
			update(l, r, x, y, val, R(id));
		else{
			update(l, mid, x, y, val, L(id));
			update(mid + 1, r, x, y, val, R(id));
		}
	}
	void query(int l, int r, int x, int y, int id){
		if (l == r){
			T[l].Q(x, y);
			Max = max(Max, T[l].Max);
			Min = min(Min, T[l].Min);
			return;
		}
		int mid = (t[id].l + t[id].r) >> 1;
		if (r <= mid)
			query(l, r, x, y, L(id));
		else if (mid < l)
			query(l, r, x, y, R(id));
		else{
			query(l, mid, x, y, L(id));
			query(mid + 1, r, x, y, R(id));
		}
	}
	void Q(int l, int r, int x, int y){
		Max = -inf; Min = inf;
		query(l, r, x, y, 1);
	}
	void P(int l, int r, int x, int y, int val){
		update(l, r, x, y, val, 1);
	}
};
int n, m;
Two_Dimension_Segment_Tree tree;
void input(){
	rd(n); rd(m);
	for (int i = 1; i <= n; i++)
	for (int j = 1; j <= m; j++)rd(a[i][j]);
}
int main(){
	input();
	tree.M = m;
	tree.build(1, n, 1);
	int q; rd(q);
	string s; int l, r, x, y, val;
	while (q-- > 0){
		cin >> s;
		if (s[0] == 'q'){
			rd(l); rd(x); rd(r); rd(y);
			tree.Q(l, r, x, y);
			printf("%d %d\n", tree.Max, tree.Min);
		}
		else {
			rd(x); rd(y); rd(val);
			tree.P(x, x, y, y, val);
		}
	}
	return 0;
}

java:

import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.Scanner;
import java.util.TreeSet;

public class Main {
	static int N = 550;
	static int inf = 1000*1000*1000;
	int[][] a = new int[N][N];
	class Segment_Tree{
		class Node{
			int l, r, max, min, lazy;
			Node(){}
			Node(int l, int r, int max, int min){
				this.l = l; this.r = r; this.max = max; this.min = min;
				lazy = inf;
			}
		}
		public Node[] t = new Node[N<<2];
		public int pos = 0, Max, Min;
		int L(int x){return x<<1;}
		int R(int x){return x<<1|1;}
		void up(int id){
			t[id].max = max(t[L(id)].max, t[R(id)].max);
			t[id].min = min(t[L(id)].min, t[R(id)].min);
			t[id].lazy = inf;
		}
		void down(int id){
			if(t[id].lazy != inf){
				t[L(id)].max = t[R(id)].max = t[id].lazy;
				t[L(id)].min = t[R(id)].min = t[id].lazy;
				t[L(id)].lazy = t[R(id)].lazy = t[id].lazy;
				t[id].lazy = inf;
			}
		}
		public void build(int l, int r, int id){
			t[id] = new Node(l, r, 0, 0);
			if(l == r){
				t[id].min = t[id].max = a[pos][l];
				return ;
			}
			int mid = (l+r)>>1;
			build(l, mid, L(id)); build(mid+1, r, R(id));
			up(id);
		}
		void update(int l, int r, int val, int id){
			if(l == t[id].l && r == t[id].r){
				t[id].max = t[id].min = t[id].lazy = val;
				return ;
			}
			down(id);
			int mid = (t[id].l + t[id].r)>>1;
			if(r <= mid)
				update(l, r, val, L(id));
			else if(mid < l)
				update(l, r, val, R(id));
			else{
				update(l, mid, val, L(id));
				update(mid+1, r, val, R(id));
			}
			up(id);
		}
		void query(int l, int r, int id){
			if(l == t[id].l && r == t[id].r){
				Min = min(Min, t[id].min);
				Max = max(Max, t[id].max);
				return;
			}
			down(id);
			int mid = (t[id].l + t[id].r)>>1;
			if(r <= mid)
				query(l, r, L(id));
			else if(mid < l)
				query(l, r, R(id));
			else{
				query(l, mid, L(id));
				query(mid+1, r, R(id));
			}
		}
		public void Q(int l, int r){
			Max = -inf; Min = inf;
			query(l, r, 1);
		}
		public void P(int l, int r, int val){
			update(l, r, val, 1);
		}
	}
	class Two_Dimension_Segment_Tree{
		class Node{
			int l, r;
			Node(){}
			Node(int l, int r){
				this.l = l; this.r = r;
			}
		}
		Node[] t = new Node[N<<2];
		Segment_Tree[] T = new Segment_Tree[N];
		int Max, Min, M;
		int L(int x){return x<<1;}
		int R(int x){return x<<1|1;}

		void build(int l, int r, int id){
			t[id] = new Node(l, r);
	//		System.out.println(l+" "+r);
			if(l == r){
				T[l] = new Segment_Tree();
				T[l].pos = l;
				T[l].build(1, M, 1);
				return ;
			}
			int mid = (l+r)>>1;
			build(l, mid, L(id)); build(mid+1, r, R(id));
		}
		void update(int l, int r, int x, int y, int val, int id){
			if(l == r){
				T[l].P(x, y, val);
				return ;
			}
			int mid = (t[id].l + t[id].r)>>1;
			if(r <= mid)
				update(l, r, x, y, val, L(id));
			else if(mid < l)
				update(l, r, x, y, val, R(id));
			else{
				update(l, mid, x, y, val, L(id));
				update(mid+1, r, x, y, val, R(id));
			}
		}
		void query(int l, int r, int x, int y, int id){
			if(l == r){
				T[l].Q(x, y);
				Max = max(Max, T[l].Max);
				Min = min(Min, T[l].Min);
				return;
			}
			int mid = (t[id].l + t[id].r)>>1;
			if(r <= mid)
				query(l, r, x, y, L(id));
			else if(mid < l)
				query(l, r, x, y, R(id));
			else{
				query(l, mid, x, y, L(id));
				query(mid+1, r, x, y, R(id));
			}
		}
		void Q(int l, int r, int x, int y){
			Max = -inf; Min = inf;
			query(l, r, x, y, 1);
		}
		void P(int l, int r, int x, int y, int val){
			update(l, r, x, y, val, 1);
		}
	}
	int n, m;
	Two_Dimension_Segment_Tree tree = new Two_Dimension_Segment_Tree();
	void input(){
		n = cin.nextInt(); m = cin.nextInt();
		for(int i = 1; i <= n; i++)
			for(int j = 1; j <= m; j++)a[i][j] = cin.nextInt();
	}
	void work() {
		input();
		tree.M = m;
		tree.build(1, n, 1);
		int q; q = cin.nextInt();
		String s; int l, r, x, y, val;
		while(q-- > 0){
			s = cin.next();
			if(s.charAt(0) == 'q'){
				l = cin.nextInt(); x = cin.nextInt(); r = cin.nextInt(); y =cin.nextInt();
				tree.Q(l, r, x, y);
				out.println(tree.Max+" "+tree.Min);
			}
			else {
				x = cin.nextInt(); y = cin.nextInt(); val = cin.nextInt();
				tree.P(x, x, y, y, val);
			}
		}
	}

	Main() {
		cin = new Scanner(System.in);
		out = new PrintWriter(System.out);
	}

	public static void main(String[] args) {
		Main e = new Main();
		e.work();
		out.close();
	}

	public Scanner cin;
	public static PrintWriter out;

	class Queue {
		int[] queue = new int[100000];
		int front, rear;

		void clear() {
			front = rear = 0;
		}

		boolean empty() {
			return front == rear;
		}

		int size() {
			return rear - front;
		}

		void push(int x) {
			queue[rear++] = x;
		}

		int top() {
			return queue[front];
		}

		void pop() {
			front++;
		}
	}
	int max(int x, int y) {
		return x > y ? x : y;
	}

	int min(int x, int y) {
		return x < y ? x : y;
	}
	double max(double x, double y) {
		return x > y ? x : y;
	}

	double min(double x, double y) {
		return x < y ? x : y;
	}

	static double eps = 1e-8;

	double abs(double x) {
		return x > 0 ? x : -x;
	}

	boolean zero(double x) {
		return abs(x) < eps;
	}
}
时间: 2024-10-04 16:20:05

Uva 11297 Census 二维线段树的相关文章

UVA 11297 Census ——二维线段树

[题目分析] 二维线段树模板题目. 简直就是无比的暴力.时间复杂度为两个log. 标记的更新方式比较奇特,空间复杂度为N^2. 模板题目. [代码] #include <cstdio> #include <cstring> //#include <cmath> #include <cstdlib> #include <map> #include <set> #include <queue> #include <str

Uva 11297.Census——二维线段树

http://www.bnuoj.com/v3/problem_show.php?pid=19715 二维线段树模板 #include <cstring> #include <cstdio> #include <algorithm> #include <iostream> #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define rep(i,n) for(int i=0

Uva 11297 Census,二维线段树,板子

维护二维矩阵. q  x1, y1, x2, y2 :   查询x1<=x<=x2, y1<=y<=y2的格子(x,y)的最大值和最小值. c    x, y, v:    修改(x,y) = v. 矩阵大小(n,m<=500). 查询次数q<=40000. #include<algorithm> using namespace std; const int INF = 1<<30; const int maxn = 2000 + 10; int

HDU1832 二维线段树求最值(模板)

Luck and Love Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 50 Accepted Submission(s): 20   Problem Description 世界上上最远的距离不是相隔天涯海角而是我在你面前可你却不知道我爱你                ―― 张小娴 前段日子,枫冰叶子给Wiskey做了个征婚启事,聘

ZOJ 2859 二维线段树

思路:自己写的第二发二维线段树1A,哈哈,看来对二维的push操作比较了解了:但是还没遇到在两个线段树中同时进行push操作的,其实这题我是想在x维和y维同时进行push操作的,但是想了好久不会,然后看到这题又给出10秒,然后想想在x维线段直接单点查询肯定也过了,然后在第二维就只有pushup操作,在第一维线段树没有pushup操作.要是在第一维也有pushup操作的话,那就不用单点查询那么慢了.不过也A了,想找题即在二维同时进行pushup和pushdown操作的. #include<iost

[POJ2155] Matrix(二维线段树,树套树)

题目链接:http://poj.org/problem?id=2155 题意:给一个01矩阵,两个操作,翻转:子矩阵里每一个数都由0变1,1变0. 查询:查询某一点是0还是1. 一直以为二维线段树就是开一个线段树数组的我- 这题暴力更新每一个小矩形,翻转就+1,最后看看某点的奇偶. 写屎了,特别注意的是在外层查询的时候要先把当前层的内层query掉,接着再向下扩展.这样外层就不用lazy啦 1 #include <algorithm> 2 #include <iostream> 3

poj1195 Mobile phones 二维线段树入门

二维线段树就是树套树,线段树套线段树... #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #define REP(i,a,b) for(int i=a;i<=b;i++) #define MS0(a) memset(a,0,sizeof(a)) #define lson l,m,rt<<1 #

tyvj P1716 - 上帝造题的七分钟 二维树状数组区间查询及修改 二维线段树

P1716 - 上帝造题的七分钟 From Riatre    Normal (OI)总时限:50s    内存限制:128MB    代码长度限制:64KB 背景 Background 裸体就意味着身体. 描述 Description “第一分钟,X说,要有矩阵,于是便有了一个里面写满了0的n×m矩阵.第二分钟,L说,要能修改,于是便有了将左上角为(a,b),右下角为(c,d)的一个矩形区域内的全部数字加上一个值的操作.第三分钟,k说,要能查询,于是便有了求给定矩形区域内的全部数字和的操作.第

POJ 2155 二维线段树

POJ 2155  二维线段树 思路:二维线段树就是每个节点套一棵线段树的树. 刚开始因为题目是求A[I,J],然后在y查询那直接ans^=Map[i][j]的时候没看懂,后面自己把图画出来了才理解. 因为只有0和1,所以可以用异或来搞,而不需要每次都需要修改. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<map> #incl