UVA 11992 Fast Matrix Operations 线段树

原创 2015年11月20日 01:19:50

大致题意:给你一个r*c的矩阵,r*c<=1e6,给你三种操作,第一种,1 x1 y1 x2 y2 u ,把[x1,y1,x2,y2]子矩阵所有的元素都加上u,第二种,2 x1 y1 x2 y2 u,把[x1,y1,x2,y2]子矩阵的所有元素变成u,第三种,3 x1 y1 x2 y2,查询[x1,y1,x2,y2]所有元素的和,最大值,最小值。

思路:开始并不知道怎么搞,直到发现了r<=20之后,直接暴力好了,反正一个查询或更新的复杂度也就20*log(N)

坑点:是我没想好,第二种操作会对第一种操作有影响,具体就是第二种操作的时候会抵消第一种操作之前所做的状态。所以要处理一下。

http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18697

#include <cstdio>
#include <cmath>
#include <iostream>

#define change(x,y) (x-1)*clo+y
#define dist(rt) (t[rt].y - t[rt].x + 1)

using namespace std;

const int MAXN = 1e6+5;

struct Node {
    int x,y;
    int add,live; //add代表这个区间加上的值,live表示把这个区间所有值变成live;
    int minnum,maxnum; //minnum 区间最小,区间最大;
    int sum; //区间内总和;
}t[MAXN<<2];

int n,m;
int row,clo;

void Push_Up(int rt) {
    t[rt].sum = t[rt<<1].sum + t[rt<<1|1].sum;
    t[rt].maxnum = max(t[rt<<1].maxnum,t[rt<<1|1].maxnum);
    t[rt].minnum = min(t[rt<<1].minnum,t[rt<<1|1].minnum);
}

void Push_Down(int rt) {
    if(t[rt].live) {
        t[rt<<1].sum = dist(rt<<1) * t[rt].live;
        t[rt<<1|1].sum = dist(rt<<1|1) * t[rt].live;
        t[rt<<1].maxnum = t[rt].live; t[rt<<1|1].maxnum = t[rt].live;
        t[rt<<1].minnum = t[rt].live; t[rt<<1|1].minnum = t[rt].live;
        t[rt<<1].live = t[rt<<1|1].live = t[rt].live;
        t[rt<<1].add  = t[rt<<1|1].add  = 0;//去掉live 对 add的影响,之前add的要全部取消掉
        t[rt].live = 0;
    }
    if(t[rt].add) {
        t[rt<<1].sum += dist(rt<<1) * t[rt].add;
        t[rt<<1|1].sum += dist(rt<<1|1) * t[rt].add;
        t[rt<<1].maxnum += t[rt].add; t[rt<<1|1].maxnum += t[rt].add;
        t[rt<<1].minnum += t[rt].add; t[rt<<1|1].minnum += t[rt].add;
        t[rt<<1].add += t[rt].add; t[rt<<1|1].add += t[rt].add;
        t[rt].add = 0;
    }

}

void Build(int x,int y,int rt) {
    t[rt].x = x; t[rt].y = y;
    t[rt].add = t[rt].live = 0;
    if(x == y) {
        t[rt].sum = 0;
        t[rt].maxnum = 0;
        t[rt].minnum = 0;
        return ;
    }
    int mid = (x + y) >> 1;
    Build(x,mid,rt<<1);
    Build(mid+1,y,rt<<1|1);
    Push_Up(rt);
}

void Update(int rt,int left,int right,int u,int flag) {
    if(t[rt].x >= left && t[rt].y <= right) {
        if(flag) {
            t[rt].sum += dist(rt) * u;
            t[rt].add += u;
            t[rt].maxnum += u;
            t[rt].minnum += u;
        }
        else {
            t[rt].sum = dist(rt) * u;
            t[rt].live = u;
            t[rt].add = 0;//去掉live 对 add的影响,之前add的要全部取消掉
            t[rt].maxnum = u;
            t[rt].minnum = u;
        }
        return ;
    }
    int mid = (t[rt].x + t[rt].y) >> 1;
    Push_Down(rt);
    if(mid >= left) Update(rt<<1,left,right,u,flag);
    if(mid < right) Update(rt<<1|1,left,right,u,flag);
    Push_Up(rt);
}

int sum ;
int maxnum , minnum;

void Query(int rt,int left,int right) {
    if(t[rt].x >= left && t[rt].y <= right) {
        sum += t[rt].sum;
        maxnum = max(maxnum,t[rt].maxnum);
        minnum = min(minnum,t[rt].minnum);
        return ;
    }
    int mid = (t[rt].x + t[rt].y) >> 1;
    Push_Down(rt);
    if(mid >= left) Query(rt<<1,left,right);
    if(mid < right) Query(rt<<1|1,left,right);
    Push_Up(rt);
}

void Print_Tree(int rt) {
    static int cnt = 0;
    Push_Down(rt);
    if(t[rt].x == t[rt].y) {
        cnt ++;
        if(cnt % 4 == 0) {
            printf("%d\n",t[rt].sum);
        }
        else {
            printf("%d ",t[rt].sum);
        }
        return ;
    }
    Print_Tree(rt<<1);
    Print_Tree(rt<<1|1);
}

void input() {
    Build(1,change(row,clo),1);
    int ok,u;
    int x1,y1,x2,y2;
    for(int i = 1 ; i <= n ; i ++) {
        //Print_Tree(1);
        scanf("%d %d %d %d %d",&ok,&x1,&y1,&x2,&y2);
        if(ok == 1) {
            scanf("%d",&u); //add 
            for(int j = x1 ; j <= x2 ; j ++) {
                Update(1,change(j,y1),change(j,y2),u,1);
            }
        }
        else if(ok == 2) { //live
            scanf("%d",&u);
            for(int j = x1 ; j <= x2 ; j ++) {
                Update(1,change(j,y1),change(j,y2),u,0);
            }
        }
        else {
            sum = 0;
            minnum = 0x3f3f3f3f;
            maxnum = 0;
            for(int j = x1 ; j <= x2 ; j ++) {
                Query(1,change(j,y1),change(j,y2));
            }
            printf("%d %d %d\n",sum,minnum,maxnum);
        }
    }
}

void solve() {

}

int main(void) {
    //freopen("a.in","r",stdin);
    while(~scanf("%d %d %d",&row,&clo,&n)) {
        input();
        solve();
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

UVA 11992 - Fast Matrix Operations(线段树)

UVA 11992 - Fast Matrix Operations 题目链接 题意:给定一个矩阵,3种操作,在一个矩阵中添加值a,设置值a,查询和 思路:由于最多20列,所以完全可以当作20个...
  • u011217342
  • u011217342
  • 2014年07月30日 03:28
  • 1209

11992 - Fast Matrix Operations (线段树)

题目链接:点击打开链接 该题是线段树的区间更新和区间求和操作, 但是注意区间更新的时候有两个操作:修改值和增加值 。    这两个操作在某些情况下会相互影响 。 细节参见代码: #inclu...
  • weizhuwyzc000
  • weizhuwyzc000
  • 2015年09月26日 09:50
  • 405

uva 11992 Fast Matrix Operations 线段树

代码:
  • a601025382s
  • a601025382s
  • 2014年08月03日 11:31
  • 1295

uva 11992 Fast Matrix Operations

【题意】 给定一个r*c(r 1 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1 2 x1 y1 x2 y2 val 表示将(x1,y1,x2,y2)(x1 3 x...
  • just_sort
  • just_sort
  • 2016年07月28日 09:03
  • 132

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

题目大意:给出一个矩阵,三种操作 1 x1 y1 x2 y2 v:将x1
  • L123012013048
  • L123012013048
  • 2015年03月27日 20:55
  • 428

UVA 11992 Fast Matrix Operations(线段树)

原题链接Problem DescriptionThere is a matrix containing at most 106 elements divided into r rows and c ...
  • xj949967574
  • xj949967574
  • 2017年02月08日 18:07
  • 110

UVa 11992 Fast Matrix Operations / 线段树成段更新

练基本功 成段更新求2维区间最大值最小值以及和 把某个区间置为v 把某个区间都加上v 难点是set与add的先后顺序的处理 如果先做add在做set那么add是没用的 所以做set时将add置为0 ...
  • u011686226
  • u011686226
  • 2014年02月04日 23:15
  • 1085

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

此题也是无数WA。
  • slowlight93
  • slowlight93
  • 2014年09月02日 18:34
  • 366

线段树(Fast Matrix Operations,UVA 11992)

我真的是写线段树写懵逼了。 开始出现成吨低级错误。 代码 #include #define m ((l+r)>>1) #define ls (now...
  • xl2015190026
  • xl2015190026
  • 2016年12月12日 17:15
  • 94

UVA - 11992 Fast Matrix Operations(线段树)

对于一个r*c的矩阵
  • u014435976
  • u014435976
  • 2014年11月22日 10:37
  • 435
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:UVA 11992 Fast Matrix Operations 线段树
举报原因:
原因补充:

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