• UVA 11992 Fast Matrix Operations (降维)


    题意:对一个矩阵进行子矩阵操作。

    元素最多有1e6个,树套树不好开(我不会),把二维坐标化成一维的,一个子矩阵操作分解成多条线段的操作。

    一次操作的复杂度是RlogC,很容易找到极端的数据(OJ上实测没有),如果判断一下然后启发式建树复杂度是min(RlogC,ClogR)。

    代码中结点没有保存l和r,而且询问是保存在全局变量中,这样做比较省空间。但是也有缺点,比如推区间结点数量的时候会麻烦一点。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 1e6+1;
    int R,C;
    
    #define lid (id<<1)
    #define rid (id<<1|1)
    struct Seg
    {
        int add,setv;
        int Max,Min,sum;
    }tr[maxn<<2];
    
    #define OP1(id,val)
    tr[id].add += val; tr[id].Max += val; tr[id].Min += val; tr[id].sum += (r-l+1)*val;
    #define OP2(id,val)
    tr[id].Max = tr[id].setv = tr[id].Min = val; tr[id].add = 0; tr[id].sum = val*(r-l+1);
    
    inline void push_down(int id,int l,int r)
    {
        int lc = lid, rc = rid, mid = (l+r)>>1;
        if(tr[id].setv>=0){
            int &t = tr[id].setv;
            swap(r,mid);
            OP2(lc,t);
            swap(l,r); l++; swap(mid,r);
            OP2(rc,t);
            l--; swap(mid,l);
            t = -1;
        }
        if(tr[id].add>0){
            int &t = tr[id].add;
            swap(r,mid);
            OP1(lc,t);
            swap(l,r); l++; swap(mid,r);
            OP1(rc,t);
            l--; swap(mid,l);
            t = 0;
        }
    }
    
    inline void maintain(int id)
    {
        int lc = lid, rc = rid;
        tr[id].sum = tr[lc].sum + tr[rc].sum;
        tr[id].Max = max(tr[lc].Max,tr[rc].Max);
        tr[id].Min = min(tr[lc].Min,tr[rc].Min);
    }
    
    int ql,qr,val;
    void add1D(int l = 0,int r = R*C-1,int id = 1)
    {
        if(ql<=l&&r<=qr) { OP1(id,val) return; }
        int mid = (l+r)>>1, lc = lid, rc = rid;
        push_down(id,l,r);
        if(ql<=mid) add1D(l,mid,lc);
        if(qr>mid) add1D(mid+1,r,rc);
        maintain(id);
    }
    
    void set1D(int l = 0,int r = R*C-1,int id = 1)
    {
        if(ql<=l&&r<=qr) { OP2(id,val) return; }
        int mid = (l+r)>>1, lc = lid, rc = rid;
        push_down(id,l,r);
        if(ql<=mid) set1D(l,mid,lc);
        if(qr>mid) set1D(mid+1,r,rc);
        maintain(id);
    }
    
    int queryMax1D(int l = 0,int r = R*C-1,int id = 1)
    {
        if(ql<=l&&r<=qr) { return tr[id].Max; }
        int mid = (l+r)>>1, lc = lid, rc = rid;
        push_down(id,l,r);
        int ret = 0;
        if(ql<=mid) ret = max(ret,queryMax1D(l,mid,lc));
        if(qr>mid) ret = max(ret,queryMax1D(mid+1,r,rc));
        return ret;
    }
    
    const int INF = 0x3f3f3f3f;
    
    int queryMin1D(int l = 0,int r = R*C-1,int id = 1)
    {
        if(ql<=l&&r<=qr) { return tr[id].Min; }
        int mid = (l+r)>>1, lc = lid, rc = rid;
        push_down(id,l,r);
        int ret = INF;
        if(ql<=mid) ret = min(ret,queryMin1D(l,mid,lc));
        if(qr>mid) ret = min(ret,queryMin1D(mid+1,r,rc));
        return ret;
    }
    
    int querySum1D(int l = 0,int r = R*C-1,int id = 1)
    {
        if(ql<=l&&r<=qr) { return tr[id].sum; }
        int mid = (l+r)>>1, lc = lid, rc = rid;
        push_down(id,l,r);
        int ret = 0;
        if(ql<=mid) ret += querySum1D(l,mid,lc);
        if(qr>mid) ret += querySum1D(mid+1,r,rc);
        return ret;
    }
    
    //[0,r)
    void add2D(int x1,int y1,int x2,int y2,int v)
    {
        val = v;
        int st = x1*C+y1, len = y2-y1;
        for(int x = x1; x <= x2; x++){
            ql = st; qr = st+len;
            add1D();
            st += C;
        }
    }
    
    void set2D(int x1,int y1,int x2,int y2,int v)
    {
        val = v;
        int st = x1*C+y1, len = y2-y1;
        for(int x = x1; x <= x2; x++){
            ql = st; qr = st+len;
            set1D();
            st += C;
        }
    }
    
    int querySum2D(int x1,int y1,int x2,int y2)
    {
        int ret = 0;
        int st = x1*C+y1, len = y2-y1;
        for(int x = x1; x <= x2; x++){
            ql = st; qr = st+len;
            ret += querySum1D();
            st += C;
        }
        return ret;
    }
    
    int queryMax2D(int x1,int y1,int x2,int y2)
    {
        int ret = 0;
        int st = x1*C+y1, len = y2-y1;
        for(int x = x1; x <= x2; x++){
            ql = st; qr = st+len;
            ret = max(ret,queryMax1D());
            st += C;
        }
        return ret;
    }
    
    int queryMin2D(int x1,int y1,int x2,int y2)
    {
        int ret = INF;
        int st = x1*C+y1, len = y2-y1;
        for(int x = x1; x <= x2; x++){
            ql = st; qr = st+len;
            ret = min(ret,queryMin1D());
            st += C;
        }
        return ret;
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        int m;
        while(~scanf("%d%d%d",&R,&C,&m)){
            ql = 0; qr = R*C-1; val = 0;
            set1D();
            while(m--){
                int op,x1,y1,x2,y2; scanf("%d%d%d%d%d",&op,&x1,&y1,&x2,&y2);
                if(op == 1){
                    int v; scanf("%d",&v);
                    add2D(x1-1,y1-1,x2-1,y2-1,v);
                }else if(op == 2){
                    int v; scanf("%d",&v);
                    set2D(x1-1,y1-1,x2-1,y2-1,v);
                }else {
                    x1--;x2--;y1--;y2--;
                    printf("%d %d %d
    ",querySum2D(x1,y1,x2,y2),queryMin2D(x1,y1,x2,y2),queryMax2D(x1,y1,x2,y2));
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    用C语言画个简单表格
    魔方阵 奇数偶数都成立
    HDU 1527 取石子游戏
    HDU 2669 Romantic
    21位花朵数(详解)
    博弈论总结(1)
    qsort排序(即快排)
    POJ 1061 青蛙的约会
    HDU 2176 取(m堆)石子游戏
    HDU1061 求n^n的最低位
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4790224.html
Copyright © 2020-2023  润新知