题目链接:点击打开链接
好久没发题解了,
第一维的线段树更新到底,叶子节点建一棵线段树。
#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;
}
}