zoukankan      html  css  js  c++  java
  • UVA 11192 Fast Matrix Operations

    UVA_11192

        如果是在一维的序列上进行这些操作的话,那么线段树就可以了。不过现在题目将这些操作拓展到了二维,回想线段树的本质是二分线段,那么对于一个二维的矩阵,拓展一下就应当是四分矩阵了。

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define MAXD 1000010
    #define INF 0x3f3f3f3f
    int N, M, P, node;
    struct SegTree
    {
        int x1, y1, x2, y2, sum, min, max, add, to, son[4], area;    
        void pushdown(); void update();
        void init()
        {
            sum = add = to = 0;
            son[0] = son[1] = son[2] = son[3] = 0;
            min = INF, max = -INF;
        }
    }st[4 * MAXD];
    inline void To(int cur, int v)
    {
        if(cur)
        {
            st[cur].to = v, st[cur].add = 0;
            st[cur].min = st[cur].max = v, st[cur].sum = v * st[cur].area;
        }
    }
    inline void Add(int cur, int v)
    {
        if(cur)
        {
            st[cur].add += v;
            st[cur].min += v, st[cur].max += v, st[cur].sum += v * st[cur].area;    
        }    
    }
    inline void SegTree::pushdown()
    {
        if(to)
        {
            for(int i = 0; i < 4; i ++) To(son[i], to);
            to = 0;
        }
        if(add)
        {
            for(int i = 0; i < 4; i ++) Add(son[i], add);
            add = 0;    
        }
    }
    inline void SegTree::update()
    {
        min = INF, max = -INF, sum = 0;
        for(int i = 0; i < 4; i ++)
        {
            sum += st[son[i]].sum;
            min = std::min(min, st[son[i]].min);
            max = std::max(max, st[son[i]].max);
        }
    }
    void build(int cur, int x1, int x2, int y1, int y2)
    {
        int midx = x1 + x2 >> 1, midy = y1 + y2 >> 1;
        st[cur].init(), st[cur].sum = st[cur].min = st[cur].max = 0;
        st[cur].x1 = x1, st[cur].x2 = x2, st[cur].y1 = y1, st[cur].y2 = y2, st[cur].area = (x2 - x1 + 1) * (y2 - y1 + 1);
        if(x1 == x2 && y1 == y2) return ;
        st[cur].son[0] = ++ node, build(node, x1, midx, y1, midy);
        if(midx < x2)
            st[cur].son[1] = ++ node, build(node, midx + 1, x2, y1, midy);
        if(midx < x2 && midy < y2)
            st[cur].son[2] = ++ node, build(node, midx + 1, x2, midy + 1, y2);
        if(midy < y2)
            st[cur].son[3] = ++ node, build(node, x1, midx, midy + 1, y2);
        st[cur].update();
    }
    void init()
    {
        st[0].init(), node = 1;
        build(1, 1, N, 1, M);
    }
    inline int inside(int k, int x1, int x2, int y1, int y2)
    {
        return st[k].x1 >= x1 && st[k].x2 <= x2 && st[k].y1 >= y1 && st[k].y2 <= y2;
    }
    inline int inter(int k, int x1, int x2, int y1, int y2)
    {
        if(st[k].x2 < x1 || st[k].x1 > x2 || st[k].y2 < y1 || st[k].y1 > y2) return 0;
        return 1;
    }
    void refresh(int cur, int x1, int x2, int y1, int y2, int v, int op)
    {
        if(inside(cur, x1, x2, y1, y2))
        {
            if(op == 1) Add(cur, v);
            else To(cur, v);
            return ;
        }
        st[cur].pushdown();
        for(int i = 0; i < 4; i ++)    
            if(st[cur].son[i] && inter(st[cur].son[i], x1, x2, y1, y2))
                refresh(st[cur].son[i], x1, x2, y1, y2, v, op);
        st[cur].update();
    }
    void query(int cur, int x1, int x2, int y1, int y2, int &sum, int &min, int &max)
    {
        if(inside(cur, x1, x2, y1, y2))
        {
            sum += st[cur].sum, min = std::min(min, st[cur].min), max = std::max(max, st[cur].max);
            return ;
        }
        st[cur].pushdown();
        for(int i = 0; i < 4; i ++)
            if(st[cur].son[i] && inter(st[cur].son[i], x1, x2, y1, y2))
                query(st[cur].son[i], x1, x2, y1, y2, sum, min, max);
    }
    void solve()
    {
        int i, op, x1, y1, x2, y2, v, min, max, sum;
        for(i = 0; i < P; i ++)
        {
            scanf("%d%d%d%d%d", &op, &x1, &y1, &x2, &y2);
            if(op == 3)
            {
                min = INF, max = -INF, sum = 0;
                query(1, x1, x2, y1, y2, sum, min, max);
                printf("%d %d %d\n", sum, min, max);
            }
            else
            {
                scanf("%d", &v);
                refresh(1, x1, x2, y1, y2, v, op);    
            }
        }
    }
    int main()
    {
        while(scanf("%d%d%d", &N, &M, &P) == 3)
        {
            init();
            solve();    
        }    
        return 0;    
    }
  • 相关阅读:
    老陈与小石头运算代码
    第五次作业
    老陈与小石头
    简易四则运算
    四则运算
    对git的认识
    第一次作业
    arcgis-tomcat-cors
    jquery deferred promise
    springloaded hot deploy
  • 原文地址:https://www.cnblogs.com/staginner/p/2654429.html
Copyright © 2011-2022 走看看