uva 11992 线段树对矩阵进行更新查询

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3143

把矩阵变成一行,然后计算位置,lrj给了线段树数组做法 但是我做的线段树空间过大,直接爆掉,所以换方法了

主要还是测试自己的线段树区间更新的模板

各种RE+WA之后AC,,,,,

做的时候出现的几个错误:

1、行和列弄错

2、build初始化的时候,mmin mmax 都初始化为0才对

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

#define lson(i) l , mid , (i)*2
#define rson(i) mid + 1 , r , ((i)*2 +1)
#define ll rt*2
#define rr (rt*2+1)

const int INFMIN = 0xffffffff;
const int INFMAX = 1000000009;//0x80000000;
const int MAXN = 30001000;
struct Node{
    int l,r;
    int mmax,mmin,sum,add,s;/*s去标记是不是被set*/
};
Node nodes[MAXN];

    int mmax,mmin,sum;
    void PushUp(int rt)
    {
        nodes[rt].mmax = max(nodes[ll].mmax,nodes[rr].mmax);
        nodes[rt].mmin = min(nodes[ll].mmin,nodes[rr].mmin);
        nodes[rt].sum = nodes[ll].sum + nodes[rr].sum;
    }
    void PushDown(int rt)
    {
        //if(nodes[rt].add && flag == 1)
        if(nodes[rt].add)
        {
            nodes[ll].add += nodes[rt].add;
            nodes[ll].mmin += nodes[rt].add;
            nodes[ll].mmax += nodes[rt].add;
            nodes[rr].add += nodes[rt].add;
            nodes[rr].mmin += nodes[rt].add;
            nodes[rr].mmax += nodes[rt].add;

            nodes[ll].sum += nodes[rt].add*(nodes[ll].r-nodes[ll].l+1);
            nodes[rr].sum += nodes[rt].add*(nodes[rr].r-nodes[rr].l+1);
            nodes[rt].add = 0;
        }
        //if(nodes[rt].s && flag == 2)
        if(nodes[rt].s)
        {
            nodes[ll].s = nodes[rr].s=nodes[rt].s;
            nodes[ll].mmin = nodes[ll].mmax = nodes[rr].mmax = nodes[rr].mmin = nodes[rt].mmax;
            nodes[ll].sum = nodes[rt].mmin*(nodes[ll].r-nodes[ll].l+1);
            nodes[rr].sum = nodes[rt].mmin*(nodes[rr].r-nodes[rr].l+1);
            nodes[ll].add = nodes[rr].add = 0;//////////////
            nodes[rt].s=0;
        }
    }
    void Build(int l,int r,int rt)
    {
        nodes[rt].l=l;
        nodes[rt].r=r;
        nodes[rt].add =0;
        nodes[rt].s=0;
        nodes[rt].sum =0;
        nodes[rt].mmin=0;
        nodes[rt].mmax=0;
        if(l == r)
        {
            //nodes[rt].mmin = nodes[rt].mmax = nodes[rt].sum =a[l];
            nodes[rt].mmin = nodes[rt].mmax = nodes[rt].sum =0;////////////////
            return ;
        }
        int mid = (nodes[rt].l+nodes[rt].r)/2;
        Build(lson(rt));
        Build(rson(rt));
        //PushUp(rt);
    }

    void Update(int l,int r,int add,int rt,int flag)
    {
/////////////////////////////////////////////////////////////////
//printf("rt=%d l=%d r=%d add=%d flag =%d nodes[rt].l=%d nodes[rt].r=%d\n",rt,l,r,add,flag,nodes[rt].l,nodes[rt].r);
        if(l<=nodes[rt].l && nodes[rt].r<=r)
        {
            if(flag == 1)/*increase*/
            {
                nodes[rt].mmax += add;
                nodes[rt].mmin += add;
                nodes[rt].add += add;
                nodes[rt].sum += add*(nodes[rt].r-nodes[rt].l+1);

            }
            else
            {
                nodes[rt].mmax = add;
                nodes[rt].mmin = add;
                nodes[rt].add=0;
                nodes[rt].s=1;
                nodes[rt].sum = add*(nodes[rt].r-nodes[rt].l+1);
            }
            return;
        }
        PushDown(rt);
        int mid = (nodes[rt].l+nodes[rt].r)/2;
        if(l<=mid)Update(l,r,add,ll,flag);
        if(r>mid)Update(l,r,add,rr,flag);
        PushUp(rt);
    }
    void Query(int l,int r,int rt)/*1表示mmin 2--mmax 3-sum*/
    {
    /////////////////////////////////////////////////////////////////
//printf("rt=%d l=%d r=%d  nodes[rt].l=%d nodes[rt].r=%d\n",rt,l,r,nodes[rt].l,nodes[rt].r);
 ///////////////////////////////////////////////////////////////////////////
        if(l<=nodes[rt].l && nodes[rt].r<=r)
        {
            mmin = min(mmin,nodes[rt].mmin);
            mmax = max(mmax,nodes[rt].mmax);
            sum += nodes[rt].sum;
            return ;
        }
        PushDown(rt);
        int mid = (nodes[rt].l+nodes[rt].r)/2;
        if(l<=mid)Query(l,r,ll);
        if(r>mid)Query(l,r,rr);
        PushUp(rt);
    }
    void clr()/*每次查询之前使用*/
    {
        sum =0;
        mmin=INFMAX;
        mmax=INFMIN;
    }

int main()
{
    //freopen("uva11992.txt","r",stdin);
    int r,c,m,v,flag,x1,y1,x2,y2;

    while(scanf("%d%d%d",&r,&c,&m)!=EOF)
    {
        Build(1,r*c,1);
        while(m--)
        {
            scanf("%d%d%d%d%d",&flag,&x1,&y1,&x2,&y2);
            if(flag<3)
            {
                scanf("%d",&v);
                for(int i=x1;i<=x2;i++)/*此处注意*/
                {
///////////////////////////////////////////////////////////////
//printf("i=%d\n",i);

                    Update(y1+(i-1)*c,y2+(i-1)*c,v,1,flag);
                }
            }
            else
            {
                int anssum=0,ansmin=INFMAX,ansmax=INFMIN;
                for(int i=x1;i<=x2;i++)
                {
                    clr();
                    Query(y1+(i-1)*c,y2+(i-1)*c,1);
                    ////////////////////////
                   // printf("**min=%d\n",mmin);
                    /////////////////
                    anssum+=sum;
                    ansmax=max(ansmax,mmax);
                    ansmin=min(ansmin,mmin);
                }
                printf("%d %d %d\n",anssum,ansmin,ansmax);
            }
        }
    }

    return 0;
}

uva 11992 线段树对矩阵进行更新查询,布布扣,bubuko.com

时间: 2024-10-05 03:32:47

uva 11992 线段树对矩阵进行更新查询的相关文章

uva 11992 线段树

因为行数比较少(最多20),所以可以考虑每行建立一颗线段树进行操作,进而想到可以只建一颗线段树,将矩阵查询变成多次线段查询.另外需要注意的是两种lazy标记的优先级,只要有赋值操作,之前的所有操作都会被替代,所以pushdown的时候要先放下赋值的lazy标记. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 using namespace std; 5 6 const int INF =

UVa 11992 (线段树 区间修改) Fast Matrix Operations

比较综合的一道题目. 二维的线段树,支持区间的add和set操作,然后询问子矩阵的sum,min,max 写完这道题也是醉醉哒,代码仓库里还有一份代码就是在query的过程中也pushdown向下传递标记. 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 const int maxnode = 1 << 17; 7 int _

uva 12299 线段树 点相关的操作模板

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=502&page=show_problem&problem=3720 唯一值得一说的就是shift,变成更新点就行 这道题主要是测试下我做的算法模板 先贴模板 /**************************************************************** 2014.4 By Pilgr

poj 1195:Mobile phones(二维线段树,矩阵求和,经典题)

Mobile phones Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 14391   Accepted: 6685 Description Suppose that the fourth generation mobile phone base stations in the Tampere area operate as follows. The area is divided into squares. The

HDOJ--4893--Wow! Such Sequence!【线段树+单点、区间更新】

链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893 题意:给你一个长度n的数列,初始都为0,有三种操作,第一种给第k个位置的数加d,第二种是查询区间 [l , r] 的总和,第三种是使区间 [l , r] 的值改为离它最近的那个斐波那契数的值. 我刚开始用sum数组存储节点的值,第三种操作是个区间更新,但是区间更新的值不一样,我就想当然的搜到最底部的节点来处理更新,果断T了.后来想了想,其实可以在节点上再加一个信息,就是这个值下次进行第三种操作要变

hdu 4893 Wow! Such Sequence!(线段树功能:单点更新,区间更新相邻较小斐波那契数)

转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4893 --------------------------------------------------------------------------------------------------------------------------------------------

POJ2886 Who Gets the Most Candies? 【线段树】+【单点更新】+【模拟】+【反素数】

Who Gets the Most Candies? Time Limit: 5000MS   Memory Limit: 131072K Total Submissions: 9416   Accepted: 2868 Case Time Limit: 2000MS Description N children are sitting in a circle to play a game. The children are numbered from 1 to N in clockwise o

HDU2795 Billboard 【线段树】+【单点更新】

Billboard Time Limit: 20000/8000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 9632    Accepted Submission(s): 4286 Problem Description At the entrance to the university, there is a huge rectangular billboard of s

POJ2828 Buy Tickets 【线段树】+【单点更新】+【逆序】

Buy Tickets Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 12296   Accepted: 6071 Description Railway tickets were difficult to buy around the Lunar New Year in China, so we must get up early and join a long queue- The Lunar New Year wa