1. 程式人生 > >Census 【UVA - 11297】【二維線段樹】

Census 【UVA - 11297】【二維線段樹】

題面

This year, there have been many problems with population calculations, since in some cities, there are many emigrants, or the population growth is very high. Every year the ACM (for Association for Counting Members) conducts a census in each region. The country is divided into N ∧ 2 regions, consisting of an N × N grid of regions. Your task is to find the least, and the greatest population in some set of regions. Since in a single year there is no significant change in the populations, the ACM modifies the population counts by some number of inhabitants.
Input
In the first line you will find N (0 ≤ N ≤ 500), in following the N lines you will be given N numbers, wich represent, the initial population of city C[i, j]. In the following line is the number Q (Q ≤ 40000), followed by Q lines with queries:
There are two possible queries:
• ‘q x1 y1 x2 y2’ which represent the coordinates of the upper left and lower right of where you must calculate the maximum and minimum change in population.
• ‘c x y v’ indicating a change of the population of city C[x, y] by value v.
Output
For each query, ‘q x1 y1 x2 y2’ print in a single line the greatest and least amount of current population.
Separated each output by a space.
Notice: There is only a single test case.


  很好的一道點更新、區間查詢問題,就是有些細節地方得注意了,找了一晚上的BUG,。。。

  題目讓你求的是區間的最大值與最小值,並且更新某點的值。


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define efs 1e-6
#define INF 2147483647
#define pi 3.141592653589793
#define e 2.718281828459045
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN = 505;
int N, Q, a[maxN][maxN], maxx[maxN<<2][maxN<<2], minn[maxN<<2][maxN<<2], ans_max, ans_min;
void pushup(int rt, int fa)
{
    maxx[fa][rt] = max(maxx[fa][rt<<1], maxx[fa][rt<<1|1]);
    minn[fa][rt] = min(minn[fa][rt<<1], minn[fa][rt<<1|1]);
}
void build_In(int rt, int fa, int pos, int l, int r, bool flag)
{
    if(l == r)
    {
        if(flag) maxx[fa][rt] = minn[fa][rt] = a[pos][l];
        else
        {
            maxx[fa][rt] = max(maxx[fa<<1][rt], maxx[fa<<1|1][rt]);
            minn[fa][rt] = min(minn[fa<<1][rt], minn[fa<<1|1][rt]);
        }
        return;
    }
    int mid = (l + r)>>1;
    build_In(rt<<1, fa, pos, l, mid, flag);
    build_In(rt<<1|1, fa, pos, mid+1, r, flag);
    pushup(rt, fa);
}
void build_Out(int rt, int l, int r)
{
    if(l == r)
    {
        build_In(1, rt, l, 1, N, true);
        return;
    }
    int mid = (l + r)>>1;
    build_Out(rt<<1, l, mid);
    build_Out(rt<<1|1, mid+1, r);
    build_In(1, rt, -1, 1, N, false);
}
void update_In(int rt, int fa, int l, int r, int qy, int val, bool flag)
{
    if(l == r)
    {
        if(flag) maxx[fa][rt] = minn[fa][rt] = val;
        else
        {
            maxx[fa][rt] = max(maxx[fa<<1][rt], maxx[fa<<1|1][rt]);
            minn[fa][rt] = min(minn[fa<<1][rt], minn[fa<<1|1][rt]);
        }
        return;
    }
    int mid = (l + r)>>1;
    if(qy>mid) update_In(rt<<1|1, fa, mid+1, r, qy, val, flag);
    else update_In(rt<<1, fa, l, mid, qy, val, flag);
    pushup(rt, fa);
}
void update_Out(int rt, int l, int r, int qx, int qy, int val)
{
    if(l == r)
    {
        update_In(1, rt, 1, N, qy, val, true);
        return;
    }
    int mid = (l + r)>>1;
    if(qx>mid) update_Out(rt<<1|1, mid+1, r, qx, qy, val);
    else update_Out(rt<<1, l, mid, qx, qy, val);
    update_In(1, rt, 1, N, qy, val, false);
}
void query_In(int rt, int fa, int l, int r, int ql, int qr, int &need_MAX, int &need_MIN)
{
    if(ql<=l && qr>=r)
    {
        need_MAX = max(need_MAX, maxx[fa][rt]);
        need_MIN = min(need_MIN, minn[fa][rt]);
        return;
    }
    int mid = (l + r)>>1;
    if(ql>mid) query_In(rt<<1|1, fa, mid+1, r, ql, qr, need_MAX, need_MIN);
    else if(qr<=mid) query_In(rt<<1, fa, l, mid, ql, qr, need_MAX, need_MIN);
    else
    {
        query_In(rt<<1|1, fa, mid+1, r, ql, qr, need_MAX, need_MIN);
        query_In(rt<<1, fa, l, mid, ql, qr, need_MAX, need_MIN);
    }
}
void query_Out(int rt, int l, int r, int qlx, int qly, int qrx, int qry, int &need_MAX, int &need_MIN)
{
    if(qlx<=l && qrx>=r)
    {
        query_In(1, rt, 1, N, qly, qry, need_MAX, need_MIN);
        return;
    }
    int mid = (l + r)>>1;
    if(qlx>mid) query_Out(rt<<1|1, mid+1, r, qlx, qly, qrx, qry, need_MAX, need_MIN);
    else if(qrx<=mid) query_Out(rt<<1, l, mid, qlx, qly, qrx, qry, need_MAX, need_MIN);
    else
    {
        query_Out(rt<<1|1, mid+1, r, qlx, qly, qrx, qry, need_MAX, need_MIN);
        query_Out(rt<<1, l, mid, qlx, qly, qrx, qry, need_MAX, need_MIN);
    }
}
int main()
{
    scanf("%d", &N);
    for(int i=1; i<=N; i++) for(int j=1; j<=N; j++) scanf("%d", &a[i][j]);
    build_Out(1, 1, N);
    scanf("%d", &Q);
    while(Q--)
    {
        char s[3];
        scanf("%s", s);
        if(s[0] == 'q')
        {
            int lx, ly, rx, ry;
            scanf("%d%d%d%d", &lx, &ly, &rx, &ry);
            ans_min = INF; ans_max = 0;
            query_Out(1, 1, N, lx, ly, rx, ry, ans_max, ans_min);
            printf("%d %d\n", ans_max, ans_min);
        }
        else
        {
            int x, y, val;
            scanf("%d%d%d", &x, &y, &val);
            update_Out(1, 1, N, x, y, val);
        }
    }
    return 0;
}