1. 程式人生 > >uva 11992Fast Matrix Operations (線段樹區間各種操作,二維轉一維)

uva 11992Fast Matrix Operations (線段樹區間各種操作,二維轉一維)

每行建立一顆線段樹,實現區間add,set查詢,注意set放在add前,每次set清空add

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1000005
#define inf 0x3f3f3f3f
#define lson 2*i,l,m
#define rson 2*i+1,m+1,r
int amax[25];
int amin[25];
int asum[25];
int setv[maxn*5];
int addv[maxn*5];
int sum[maxn*5];
int maxv[maxn*5];
int minv[maxn*5];
int r,c,m;
using namespace std;
void build(int k,int i,int l,int r)
{
    int t=k*4*c;
    setv[t+i]=-1;
    addv[t+i]=0;
    sum[t+i]=0;
    minv[t+i]=0;
    maxv[t+i]=0;
    if(l==r)
    return ;
    int m=(l+r)/2;
    build(k,lson);
    build(k,rson);


}
void pushdown(int k,int i,int l,int r)
{
    int t=k*4*c;
    int m=(l+r)/2;
    if(setv[t+i]!=-1)
    {if(l!=r)
        {addv[t+i*2]=addv[t+i*2+1]=0;
        setv[t+i*2]=setv[t+i*2+1]=setv[t+i];
        sum[t+i*2]=setv[t+i]*(m-l+1);
        sum[t+i*2+1]=setv[t+i]*(r-m);
        maxv[t+i*2]=maxv[t+i*2+1]=minv[t+i*2]=minv[t+i*2+1]=setv[t+i];

        }
        setv[t+i]=-1;
    }
    if(addv[t+i]>0)
    {if(l!=r)
        {addv[t+i*2]+=addv[t+i];
        addv[t+i*2+1]+=addv[t+i];
        sum[t+i*2]+=addv[t+i]*(m-l+1);
        sum[t+i*2+1]+=addv[t+i]*(r-m);
        maxv[t+i*2+1]+=addv[t+i];
        maxv[t+i*2]+=addv[t+i];
        minv[t+i*2]+=addv[t+i];
        minv[t+i*2+1]+=addv[t+i];

    }
    addv[t+i]=0;

}
}
void pushup(int k,int i,int l,int r)
{
    int t=k*4*c;
    sum[t+i]=sum[t+i*2]+sum[t+i*2+1];
    maxv[t+i]=max(maxv[t+i*2],maxv[t+i*2+1]);
    minv[t+i]=min(minv[t+i*2],minv[t+i*2+1]);
}
void updateadd(int k,int ql,int qr,int v,int i,int l,int r)
{
    int t=k*4*c;
    if(ql<=l&&r<=qr)
    {
        addv[t+i]+=v;
        sum[t+i]+=v*(r-l+1);
        maxv[t+i]+=v;
        minv[t+i]+=v;
        return ;
    }
    pushdown(k,i,l,r);
    int m=(l+r)>>1;
    if(ql<=m)
    updateadd(k,ql,qr,v,lson);
    if(m<qr)
    updateadd(k,ql,qr,v,rson);
    pushup(k,i,l,r);

}
void updateset(int k,int ql,int qr,int v,int i,int l,int r)
{
    int t=k*4*c;
    if(ql<=l&&r<=qr)
    {
        setv[t+i]=v;
        addv[t+i]=0;
        sum[t+i]=v*(r-l+1);
        maxv[t+i]=v;
        minv[t+i]=v;
        return ;
    }
    pushdown(k,i,l,r);
    int m=(l+r)/2;
    if(ql<=m)
    updateset(k,ql,qr,v,lson);
    if(m<qr)
    updateset(k,ql,qr,v,rson);
    pushup(k,i,l,r);
}
void query(int k,int ql,int qr,int i,int l,int r)
{
    int t=k*4*c;
    if(ql<=l&&r<=qr)
    {
        asum[k]+=sum[t+i];
        amin[k]=min(amin[k],minv[t+i]);
        amax[k]=max(amax[k],maxv[t+i]);
        return ;

    }
    pushdown(k,i,l,r);
    int m=(l+r)/2;
    if(ql<=m)
    query(k,ql,qr,lson);
    if(m<qr)
    query(k,ql,qr,rson);
}
int main()
{
    while(~scanf("%d%d%d",&r,&c,&m))
    {for(int i=1;i<=r;i++)
    build(i,1,1,c);
        while(m--)
        {
            int op,x1,x2,y1,y2,v;
            scanf("%d%d%d%d%d",&op,&x1,&y1,&x2,&y2);

            if(op!=3)
    scanf("%d",&v);
    if(op==1)
    {
        for(int i=x1;i<=x2;i++)
        updateadd(i,y1,y2,v,1,1,c);

    }
    else if(op==2)
    {
        for(int i=x1;i<=x2;i++)
        updateset(i,y1,y2,v,1,1,c);
    }

    else if(op==3)
    {
        memset(asum,0,sizeof(asum));
        for(int i=0;i<=r;i++)
        {
            amax[i]=-inf;
            amin[i]=inf;

        }
        int sumv=0,minv=inf,maxv=-inf;
        for(int i=x1;i<=x2;i++)
        {query(i,y1,y2,1,1,c);
        sumv+=asum[i];
        maxv=max(maxv,amax[i]);
        minv=min(minv,amin[i]);
    }
    printf("%d %d %d\n",sumv,minv,maxv);

    }
        }


}
return 0;
}