您的位置:首页 > 运维架构

UVA 11992 Fast Matrix Operations

2016-11-05 22:36 381 查看
题目链接:UVA 11992 Fast Matrix Operations




分析:

其实这题只用把矩阵完全看成一维的一排数,开一个数组建一个线段树,就行了。然而我却傻傻的每行开了一个线段树,代码有点丑,不要在意。

主要是set操作和Add操作之间的关系要搞清楚。

因为始终是先处理set再处理add,所以set标记传递的时候必须把add标记改为0(代码中有注释),这里很容易忘掉,导致WA。

还有add标记的初值是0(反倒不能弄成-1),Set标记的初值是-1,这两个都很容易错。

代码如下:

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
#define CLEAR(xxx) memset(xxx,0,sizeof(xxx))
using namespace std;
const int maxn=1000000+5,inf=1e9;

template <typename T>
inline void _read(T &x){
char ch=getchar(); bool mark=false;
for(;!isdigit(ch);ch=getchar())if(ch=='-')mark=true;
for(x=0;isdigit(ch);ch=getchar())x=x*10+ch-'0';
if(mark)x=-x;
}

int r,c,m,x1,y1,x2,y2;
int maxv[maxn*4][21],minv[maxn*4][21],sum[maxn*4][21];
int lazy[maxn*4][21],addv[maxn*4][21];

void pushdown(int o,int L,int R,int id){
int ls=o<<1,rs=ls+1,mid=(L+R)>>1;
if(lazy[o][id]!=-1){
addv[ls][id]=addv[rs][id]=0; //这里很重要
maxv[ls][id]=maxv[rs][id]=lazy[o][id];
minv[ls][id]=minv[rs][id]=lazy[o][id];
lazy[ls][id]=lazy[rs][id]=lazy[o][id];
sum[ls][id]=(mid-L+1)*lazy[o][id];
sum[rs][id]=(R-mid)*lazy[o][id];
lazy[o][id]=-1;
}
if(addv[o][id]){
maxv[ls][id]+=addv[o][id];
minv[ls][id]+=addv[o][id];
maxv[rs][id]+=addv[o][id];
minv[rs][id]+=addv[o][id];
sum[ls][id]+=(mid-L+1)*addv[o][id];
sum[rs][id]+=(R-mid)*addv[o][id];
addv[ls][id]+=addv[o][id];
addv[rs][id]+=addv[o][id];
addv[o][id]=0;
}
}

void Maintain(int o,int id){
maxv[o][id]=max(maxv[o<<1][id],maxv[o*2+1][id]);
minv[o][id]=min(minv[o<<1][id],minv[o*2+1][id]);
sum[o][id]=sum[o<<1][id]+sum[o*2+1][id];
}

void Update(int o,int L,int R,int v,int id){
if(lazy[o][id]!=-1||addv[o][id])pushdown(o,L,R,id);
if(y1<=L&&y2>=R){
maxv[o][id]+=v;
minv[o][id]+=v;
sum[o][id]+=(R-L+1)*v;
addv[o][id]+=v;
return ;
}
int mid=(L+R)>>1;
if(y1<=mid) Update(o<<1,L,mid,v,id);
if(y2>mid) Update(o*2+1,mid+1,R,v,id);
Maintain(o,id);
}

void update(int o,int L,int R,int v,int id){
if(lazy[o][id]!=-1||addv[o][id])pushdown(o,L,R,id);
if(y1<=L&&y2>=R){
maxv[o][id]=v;
minv[o][id]=v;
sum[o][id]=v*(R-L+1);
lazy[o][id]=v; addv[o][id]=0;
return ;
}
int mid=(L+R)>>1;
if(y1<=mid) update(o<<1,L,mid,v,id);
if(y2>mid) update(o*2+1,mid+1,R,v,id);
Maintain(o,id);
}

int Query(int o,int L,int R,int id){ //Max
if(lazy[o][id]!=-1||addv[o][id]) pushdown(o,L,R,id);
if(y1<=L&&y2>=R) return maxv[o][id];
int Max=0,mid=(L+R)>>1;
if(y1<=mid) Max=max(Max,Query(o<<1,L,mid,id));
if(y2>mid) Max=max(Max,Query(o*2+1,mid+1,R,id));
return Max;
}

int query(int o,int L,int R,int id){ //Min
if(lazy[o][id]!=-1||addv[o][id]) pushdown(o,L,R,id);
if(y1<=L&&y2>=R) return minv[o][id];
int Min=inf,mid=(L+R)>>1;
if(y1<=mid) Min=min(Min,query(o<<1,L,mid,id));
if(y2>mid) Min=min(Min,query(o*2+1,mid+1,R,id));
return Min;
}

int Getsum(int o,int L,int R,int id){
if(lazy[o][id]!=-1||addv[o][id]) pushdown(o,L,R,id);
if(y1<=L&&y2>=R) return sum[o][id];
int Sum=0,mid=(L+R)>>1;
if(y1<=mid) Sum+=Getsum(o<<1,L,mid,id);
if(y2>mid) Sum+=Getsum(o*2+1,mid+1,R,id);
return Sum;
}

void Solve(){
int op,v,i;
_read(c);_read(m);
CLEAR(maxv); CLEAR(minv); CLEAR(addv);CLEAR(sum);
memset(lazy,-1,sizeof(lazy));
while(m--){
_read(op);
_read(x1); _read(y1);_read(x2); _read(y2);
if(op==1){ //Add
_read(v);
for(i=x1;i<=x2;i++)Update(1,1,c,v,i);
}
else if(op==2){
_read(v);
for(i=x1;i<=x2;i++) update(1,1,c,v,i);
}
else {
int Max=0,Min=inf,Sum=0;
for(i=x1;i<=x2;i++){
Max=max(Max,Query(1,1,c,i));
Min=min(Min,query(1,1,c,i));
Sum+=Getsum(1,1,c,i);
}
printf("%d %d %d\n",Sum,Min,Max);
}
}
}

int main(){
while(cin>>r)Solve();
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: