uva11297 - Census 线段树套线段树

原创 2015年07月08日 17:23:47

C. Census
Time Limit: 8 sec

Description

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 x 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.

The Input

In the first line you will find N (0 <= N <= 500), in following the N lines you will be given N numbers, which 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: 

- "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. 

- "x y v" indicating a change of the population of city C [x, y] by value v.

The Output

For each query, "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.

Sample Input Sample Output
5 5
1 2 3 4 5
0 9 2 1 3
0 2 3 4 1
0 1 2 4 5
8 5 3 1 4
4
q 1 1 2 3
c 2 3 10
q 1 1 5 5
q 1 2 2 2 
9 0
10 0
9 2

  两种操作,一种是改变某一个位置的值,另一种是询问一个矩阵内的最大最小值。

  假设有x线段树和y线段树,所有的行组成x树,每行对应一个y树。更新的时候对x进行更新[x1,x2]这个区间,对这个区间x上每个点更新y树的[y1,y2]区间,更新y的叶子结点时,如果y树对应的x是叶子结点,那么直接把maxv和minv都变成v,否则maxv[id][o]=max(maxv[id<<1][o],maxv[id<<1|1][o]);minv[id][o]=min(minv[id<<1][o],minv[id<<1|1][o]);因为x叶子节点对应的y这个位置已经更新过,因此用来更新x非叶子结点也就是包含的是一个区间时x对应的y。y非叶子节点的时候由叶子结点递归上来更新就行了。这个题关键就在于对x非叶子节点的y的更新,不是很好理解。

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<algorithm>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;

const int MAXN=510;
const int MAXNODE=4*MAXN;
const int INF=0x3f3f3f3f;

int N,M,Q;
int ansMax,ansMin;

struct SegmentTree{
    int maxv[MAXNODE][MAXNODE];
    int minv[MAXNODE][MAXNODE];

    void clear(){
        memset(maxv,-INF,sizeof(maxv));
        memset(minv,INF,sizeof(minv));
    }

    void updateSub(int o,int L,int R,int ql,int qr,int id,int v,int flag){
        if(ql<=L&&qr>=R){
            if(flag){
                maxv[id][o]=v;
                minv[id][o]=v;
            }
            else{
                maxv[id][o]=max(maxv[id<<1][o],maxv[id<<1|1][o]);
                minv[id][o]=min(minv[id<<1][o],minv[id<<1|1][o]);
            }
            return;
        }
        int mid=L+(R-L)/2;
        if(ql<=mid) updateSub(o<<1,L,mid,ql,qr,id,v,flag);
        if(qr>mid) updateSub(o<<1|1,mid+1,R,ql,qr,id,v,flag);
        maxv[id][o]=max(maxv[id][o<<1],maxv[id][o<<1|1]);
        minv[id][o]=min(minv[id][o<<1],minv[id][o<<1|1]);
    }

    void update(int o,int L,int R,int ql,int qr,int subl,int subr,int v){
        if(ql<=L&&qr>=R){
            updateSub(1,1,M,subl,subr,o,v,1);
            return;
        }
        int mid=L+(R-L)/2;
        if(ql<=mid) update(o<<1,L,mid,ql,qr,subl,subr,v);
        if(qr>mid) update(o<<1|1,mid+1,R,ql,qr,subl,subr,v);
        updateSub(1,1,M,subl,subr,o,v,0);
    }

    void querySub(int o,int L,int R,int ql,int qr,int id){
        if(ql<=L&&qr>=R){
            ansMax=max(ansMax,maxv[id][o]);
            ansMin=min(ansMin,minv[id][o]);
            return;
        }
        int mid=L+(R-L)/2;
        if(ql<=mid) querySub(o<<1,L,mid,ql,qr,id);
        if(qr>mid) querySub(o<<1|1,mid+1,R,ql,qr,id);
    }

    void query(int o,int L,int R,int ql,int qr,int subl,int subr){
        if(ql<=L&&qr>=R){
            querySub(1,1,M,subl,subr,o);
            return;
        }
        int mid=L+(R-L)/2;
        if(ql<=mid) query(o<<1,L,mid,ql,qr,subl,subr);
        if(qr>mid) query(o<<1|1,mid+1,R,ql,qr,subl,subr);
    }
}tree;

int main(){
    freopen("in.txt","r",stdin);
    while(scanf("%d%d",&N,&M)!=EOF){
        tree.clear();
        int t;
        for(int i=1;i<=N;i++)
            for(int j=1;j<=M;j++){
                scanf("%d",&t);
                tree.update(1,1,N,i,i,j,j,t);
            }
        int x1,y1,x2,y2,v;
        char str[10];
        scanf("%d",&Q);
        while(Q--){
            ansMax=-INF,ansMin=INF;
            scanf("%s",str);
            if(str[0]=='c'){
                scanf("%d%d%d",&x1,&y1,&v);
                tree.update(1,1,N,x1,x1,y1,y1,v);
            }
            else{
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                tree.query(1,1,N,x1,x2,y1,y2);
                printf("%d %d\n",ansMax,ansMin);
            }
        }
    }
    return 0;
}



树套树之线段树套线段树(POJ2155 Matrix)

表示知道线段树的人做一道二维线段树就应当会了。。。 所以这里直接给出例题。Matrix(POJ 2155) 题目传送门 题目描述: 给出一个N*N的矩阵A, 它的元素都是0或1,A[i,j]表示...
  • Sunshine_cfbsl
  • Sunshine_cfbsl
  • 2016年08月11日 17:01
  • 701

树套树-线段树套线段树

线段树套线段树简单应用。
  • zzkksunboy
  • zzkksunboy
  • 2017年04月17日 20:36
  • 383

树套树(线段树套平衡树)—— ZOJ 2112 Dynamic Rankings

对应题目链接:点击打开链接 Dynamic Rankings Time Limit: 10000MS   Memory Limit: 32768KB   64bit IO Format: ...
  • u013351484
  • u013351484
  • 2015年11月22日 11:48
  • 882

POJ 2155 树套树—线段树套线段树

Matrix 楼教主出的题目。 题意:一个矩阵初始值都为0,每次给“C X1 Y1 X2 Y2" 去反转这个矩阵。或者"Q X1 Y1"查询这个点是0/1。 第一次接触树套树的题目。 一句AC:...
  • gg_gogoing
  • gg_gogoing
  • 2014年10月29日 10:00
  • 1225

【bzoj4553】【Tjoi2016】【Heoi2016】【序列】【树套树】【线段树套线段树】

题目大意给出长度为n的序列a,有m次变化。每次变化把a[x]改成b[x],一个位可以多次修改,变化相对独立。选出最长字串,在m次变化与原串中都是不下降的。题解通过分析可知,设f[i]为前i位中一定选了...
  • chunkitlau
  • chunkitlau
  • 2016年07月12日 11:11
  • 171

BZOJ 3110 ZJOI 2013 K大数查询 树套树(权值线段树套区间线段树)

题目大意:有一些位置,这些位置上可以放若干个数字。现在有两种操作。 1.在区间l到r上添加一个数字x 2.求出l到r上的第k大的数字是什么 思路:这种题一看就是树套树,关键是怎么套,怎么...
  • jiangyuze831
  • jiangyuze831
  • 2014年10月09日 14:03
  • 1158

【BZOJ3110】【Zjoi2013】K大数查询 树套树 权值线段树套区间线段树

题解: 外层权值线段树,内层区间线段树可解。 权值都是1~n,就不用离散化了。 我写了标记永久化。 其它心得神马的: 天生对树形数据结构无爱。 第一次写树套树,终于知道是怎么回事了。 (只针对...
  • Vmurder
  • Vmurder
  • 2015年01月22日 15:14
  • 2172

[Treap套权值线段树 线段树分裂与合并] BZOJ 4552 [Tjoi2016&Heoi2016]排序

线段树合并写了不少 分裂是第一次 直接每一个有序区间用一棵权值线段树维护有哪些数 外层用treap维护顺序 然后排序就把代表这段的很多颗线段树合并在一起 两端处会割开某个有序区间 会涉及分裂操作...
  • u014609452
  • u014609452
  • 2017年01月30日 19:34
  • 465

线段树套treap三题

bzoj3259动态逆序对http://www.lydsy.com/JudgeOnline/problem.php?id=3295题意:对于序列A,它的逆序对数定义为满足itip:先树状数组处理一下逆...
  • zjy2015302395
  • zjy2015302395
  • 2017年05月26日 02:01
  • 156

[BZOJ3295][Cqoi2011]动态逆序对(树状数组套线段树||cdq分治)

总有一天 能让这欢喜的歌声传到你身边
  • Clove_unique
  • Clove_unique
  • 2016年04月28日 14:10
  • 606
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:uva11297 - Census 线段树套线段树
举报原因:
原因补充:

(最多只允许输入30个字)