Uva-11992-Fast Matrix Operations

来源:互联网 发布:学校网络舆情监控制度 编辑:程序博客网 时间:2024/03/29 00:41

这个题是一道线段树题,要求进行区间修改设置以及求和。

大意是说给你一个矩阵,然后有3种操作:

1  x1 y1 x2 y2 val是将矩阵x1 y1 x2 y2的区间内的值全部增加val

2 x1 y1 x2 y2 val是将矩阵x1 y1 x2 y2的区间内的值全部设置为val

3 x1 y1 x2 y2 求出x1 y1 x2 y2的区间内的和,最大值,最小值。

从题目中的描述和要求可以看出这个题属于线段树题,而且要进行区间的操作,其中注意x,y与行列的对应,我最初在这里弄反了,导致一直RE和WA,悲剧~

代码:

#include<cstdio>#include<cstring>#include<iostream>#define MAX 3000100using namespace std;struct node{    int l,r;    int mini,maxi,sum;    int add,set;}a[MAX];int anssum,ansmin,ansmax,r,c,m;const int inf=1000000009;void built(int l,int r,int index){    a[index].l=l;a[index].r=r;a[index].add=0;a[index].set=-1;a[index].sum=a[index].mini=a[index].maxi=0;    if(l==r)return;    int mid=l+(r-l)/2;    built(l,mid,index<<1);built(mid+1,r,index<<1|1);}void pushdown(int index){    if(a[index].l>=a[index].r)return;    if(a[index].set!=-1)    {a[index<<1].set=a[index<<1|1].set=a[index].set;a[index<<1].mini=a[index<<1|1].mini=a[index].set;a[index<<1].maxi=a[index<<1|1].maxi=a[index].set;a[index<<1].add=a[index<<1|1].add=0;a[index<<1].sum=(a[index<<1].r-a[index<<1].l+1)*a[index].set;a[index<<1|1].sum=(a[index<<1|1].r-a[index<<1|1].l+1)*a[index].set;    }    if(a[index].add>0)    {int ita=a[index].add;a[index<<1].add+=ita;a[index<<1|1].add+=ita;a[index<<1].mini+=ita;a[index<<1|1].mini+=ita;a[index<<1].maxi+=ita;a[index<<1|1].maxi+=ita;a[index<<1].sum+=ita*(a[index<<1].r-a[index<<1].l+1);a[index<<1|1].sum+=ita*(a[index<<1|1].r-a[index<<1|1].l+1);    }}void maintain(int index){    if(a[index].l>=a[index].r)return;    a[index].maxi=max(a[index<<1].maxi,a[index<<1|1].maxi);    a[index].mini=min(a[index<<1].mini,a[index<<1|1].mini);    a[index].sum=a[index<<1].sum+a[index<<1|1].sum;}void updateSet(int L,int R,int val,int index){    if(a[index].l==L&&a[index].r==R)    {a[index].set=val;a[index].maxi=val;a[index].mini=val;a[index].add=0;a[index].sum=(a[index].r-a[index].l+1)*val;return;    }    pushdown(index);    a[index].set=-1;    a[index].add=0;    int mid=a[index].l+(a[index].r-a[index].l)/2;    if(R<=mid)updateSet(L,R,val,index<<1);    else if(L>mid)updateSet(L,R,val,index<<1|1);    else    {updateSet(L,mid,val,index<<1);updateSet(mid+1,R,val,index<<1|1);    }    maintain(index);}void updateAdd(int L,int R,int val,int index){    if(a[index].l==L&&a[index].r==R)    {a[index].add+=val;a[index].maxi+=val;a[index].mini+=val;a[index].sum+=(a[index].r-a[index].l+1)*val;return ;    }    pushdown(index);    a[index].set=-1;    a[index].add=0;    int mid=a[index].l+(a[index].r-a[index].l)/2;    if(R<=mid)updateAdd(L,R,val,index<<1);    else if(L>mid)updateAdd(L,R,val,index<<1|1);    else    {updateAdd(L,mid,val,index<<1);updateAdd(mid+1,R,val,index<<1|1);    }    maintain(index);}void Query(int L,int R,int index){    if(a[index].l==L&&a[index].r==R)    {anssum+=a[index].sum;ansmin=min(ansmin,a[index].mini);ansmax=max(ansmax,a[index].maxi);return;    }    pushdown(index);    a[index].set=-1;    a[index].add=0;    int mid=a[index].l+(a[index].r-a[index].l)/2;    if(R<=mid)Query(L,R,index<<1);    else if(L>mid)Query(L,R,index<<1|1);    else    {Query(L,mid,index<<1);Query(mid+1,R,index<<1|1);    }    maintain(index);}int main(){    while(scanf("%d%d%d",&r,&c,&m)!=EOF)    {built(1,r*c,1);int op,x1,x2,y1,y2,val;while(m--){    scanf("%d",&op);    if(op==1)    {scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&val);for(int i=x1;i<=x2;i++)    updateAdd((i-1)*c+y1,(i-1)*c+y2,val,1);    }    else if(op==2)    {scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&val);for(int i=x1;i<=x2;i++)    updateSet((i-1)*c+y1,(i-1)*c+y2,val,1);    }    else    {scanf("%d%d%d%d",&x1,&y1,&x2,&y2);anssum=0;ansmin=inf;ansmax=-inf;for(int i=x1;i<=x2;i++)    Query((i-1)*c+y1,(i-1)*c+y2,1);printf("%d %d %d\n",anssum,ansmin,ansmax);    }}    }    return 0;}


原创粉丝点击