zoukankan      html  css  js  c++  java
  • UVA 11992 Fast Matrix Operations (二维线段树)

    解法:因为至多20行,所以至多建20棵线段树,每行建一个。具体实现如下,有些复杂,慢慢看吧。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    #define N 1000010
    
    struct node
    {
        int mini,maxi,sum;
        int addmark,setmark;
    }tree[21][4*N];
    
    int i;
    
    void pushup(int i,int rt)
    {
        tree[i][rt].sum = tree[i][2*rt].sum + tree[i][2*rt+1].sum;
        tree[i][rt].mini = min(tree[i][2*rt].mini,tree[i][2*rt+1].mini);
        tree[i][rt].maxi = max(tree[i][2*rt].maxi,tree[i][2*rt+1].maxi);
    }
    
    void build(int i,int l,int r,int rt)
    {
        tree[i][rt].sum = tree[i][rt].mini = tree[i][rt].maxi = 0;
        tree[i][rt].setmark = -1;
        tree[i][rt].addmark = 0;
        if(l == r)
            return;
        int mid = (l+r)/2;
        build(i,l,mid,2*rt);
        build(i,mid+1,r,2*rt+1);
        pushup(i,rt);
    }
    
    void pushdown(int i,int l,int r,int rt)
    {
        if(tree[i][rt].setmark == -1 && tree[i][rt].addmark == 0)
            return;
        int mid = (l+r)/2;
        if(tree[i][rt].setmark >= 0)
        {
            tree[i][2*rt].sum = tree[i][rt].setmark*(mid-l+1);
            tree[i][2*rt+1].sum = tree[i][rt].setmark*(r-mid);
            tree[i][2*rt].mini = tree[i][2*rt+1].mini = tree[i][rt].setmark;  // 
            tree[i][2*rt].maxi = tree[i][2*rt+1].maxi = tree[i][rt].setmark;  //
            tree[i][2*rt].addmark = tree[i][2*rt+1].addmark = 0;  //
            tree[i][2*rt].setmark = tree[i][2*rt+1].setmark = tree[i][rt].setmark;
            tree[i][rt].setmark = -1;
        }
        if(tree[i][rt].addmark > 0)
        {
            tree[i][2*rt].sum += tree[i][rt].addmark*(mid-l+1);
            tree[i][2*rt+1].sum += tree[i][rt].addmark*(r-mid);
            tree[i][2*rt].maxi += tree[i][rt].addmark;  //
            tree[i][2*rt].mini += tree[i][rt].addmark;
            tree[i][2*rt+1].maxi += tree[i][rt].addmark;
            tree[i][2*rt+1].mini += tree[i][rt].addmark;  //
            tree[i][2*rt].addmark += tree[i][rt].addmark;
            tree[i][2*rt+1].addmark += tree[i][rt].addmark;
            tree[i][rt].addmark = 0;
        }
    }
    
    void add(int l,int r,int aa,int bb,int val,int rt)
    {
        if(aa>r||bb<l)
            return;
        if(aa<=l&&bb>=r)
        {
            tree[i][rt].addmark += val;
            //tree[i][rt].setmark = -1;
            tree[i][rt].sum += (r-l+1)*val;
            tree[i][rt].maxi += val;
            tree[i][rt].mini += val;
            return;
        }
        pushdown(i,l,r,rt);
        int mid = (l+r)/2;
        if(aa<=mid)
            add(l,mid,aa,bb,val,2*rt);
        if(bb>mid)
            add(mid+1,r,aa,bb,val,2*rt+1);
        pushup(i,rt);
    }
    
    void setval(int l,int r,int aa,int bb,int val,int rt)
    {
        if(aa>r||bb<l)
            return;
        if(aa<=l&&bb>=r)
        {
            tree[i][rt].setmark = val;
            tree[i][rt].addmark = 0;
            tree[i][rt].sum = val*(r-l+1);
            tree[i][rt].maxi = tree[i][rt].mini = val;
            return;
        }
        pushdown(i,l,r,rt);
        int mid = (l+r)/2;
        if(aa<=mid)
            setval(l,mid,aa,bb,val,2*rt);
        if(bb>mid)
            setval(mid+1,r,aa,bb,val,2*rt+1);
        pushup(i,rt);
    }
    
    struct node_ans
    {
        int sum;
        int mini,maxi;
    };
    
    node_ans query(int l,int r,int aa,int bb,int rt)
    {
        node_ans res,ka1,ka2;
        if(aa<=l && bb>=r)
        {
            res.sum = tree[i][rt].sum;
            res.maxi = tree[i][rt].maxi;
            res.mini = tree[i][rt].mini;
            return res;
        }
        pushdown(i,l,r,rt);
        int mid = (l+r)/2;
        if(bb<=mid)
            return query(l,mid,aa,bb,2*rt);
        else if(aa>mid)
            return query(mid+1,r,aa,bb,2*rt+1);
        else
        {
            ka1 = query(l,mid,aa,bb,2*rt);
            ka2 = query(mid+1,r,aa,bb,2*rt+1);
            res.sum = ka1.sum + ka2.sum;
            res.maxi = max(ka1.maxi,ka2.maxi);
            res.mini = min(ka1.mini,ka2.mini);
            return res;
        }
    }
    
    int main()
    {
        int r,c,m;
        int k,zuo;
        int x1,y1,x2,y2,val;
        int sum,mmax,mmin;
        while(scanf("%d%d%d",&r,&c,&m)!=EOF)
        {
            for(i=1;i<=r;i++)
            {
                build(i,1,c,1);
            }
            for(k=0;k<m;k++)
            {
                scanf("%d",&zuo);
                if(zuo == 1)
                {
                    scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&val);
                    for(i=x1;i<=x2;i++)
                    {
                        add(1,c,y1,y2,val,1);
                    }
                }
                else if(zuo == 2)
                {
                    scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&val);
                    for(i=x1;i<=x2;i++)
                    {
                        setval(1,c,y1,y2,val,1);
                    }
                }
                else 
                {
                    scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                    node_ans la;
                    sum = 0;
                    mmax = -Mod;
                    mmin = Mod;
                    for(i=x1;i<=x2;i++)
                    {
                        la = query(1,c,y1,y2,1);
                        sum += la.sum;
                        mmax = max(mmax,la.maxi);
                        mmin = min(mmin,la.mini);
                    }
                    printf("%d %d %d
    ",sum,mmin,mmax);
                }
            }
        }
    }
    View Code
  • 相关阅读:
    static,匿名对象
    构造方法
    面向对象
    数组拷贝,可变参数,foreach
    毕业设计 之 七 参考文献综述
    毕业设计 之 六 网站搭建学习笔记
    毕业设计 之 五 PHP语法学习笔记
    毕业设计 之 四 英文资料翻译
    毕业设计 之 三 mooodle及bigbluebutton使用笔记(未完成)
    毕业设计 之 二 PHP集成环境(Dreamweaver)使用
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3561449.html
Copyright © 2011-2022 走看看