uva 11992 - Fast Matrix Operations

时间:2023-03-09 16:11:47
uva 11992 - Fast Matrix Operations

简单的线段树的题;

有两种方法写这个题,目前用的熟是这种慢点的;

不过不知道怎么老是T;

感觉网上A过的人的时间度都好小,但他们都是用数组实现的

难道是指针比数组慢?

好吧,以后多用数组写写吧!

超时的代码:

 #include<cstdio>
#include<cstring>
#include<algorithm>
#define maxn 1000009
using namespace std; struct node
{
int l,r;
int ma,mi,sum;
int ad,st;
bool flag1,flag2;
node *left,*right;
} no[maxn*];
int nonocount; void build(node *rt,int l,int r)
{
rt->l=l;
rt->r=r;
rt->sum=;
rt->ma=;
rt->mi=;
if(l==r)
return;
int mid=(l+r)>>;
rt->left=no+nonocount++;
rt->right=no+nonocount++;
build(rt->left,l,mid);
build(rt->right,mid+,r);
} void maintain(node *rt)
{
rt->ma=max(rt->left->ma,rt->right->ma);
rt->mi=min(rt->left->mi,rt->right->mi);
rt->sum=rt->left->sum+rt->right->sum;
} void pushdown(node *rt)
{
if(rt->flag1==)
{
rt->flag1=;
rt->ma+=rt->ad;
rt->mi+=rt->ad;
rt->sum+=(rt->r-rt->l+)*rt->ad;
if(rt->l!=rt->r)
{
rt->left->ad=rt->right->ad=rt->ad;
rt->left->flag1=rt->right->flag1=;
pushdown(rt->left);
pushdown(rt->right);
}
rt->ad=;
return;
}
if(rt->flag2==)
{
rt->flag2=;
rt->sum=(rt->r-rt->l+)*rt->ad;
rt->ma=rt->mi=rt->ad;
if(rt->l!=rt->r)
{
rt->left->ad=rt->right->ad=rt->ad;
rt->left->flag2=rt->right->flag2=;
pushdown(rt->left);
pushdown(rt->right);
}
rt->ad=;
return;
}
} void add(node *rt,int l,int r,int v)
{
if(l==rt->l&&r==rt->r)
{
rt->ad=v;
rt->flag1=;
pushdown(rt);
return;
}
int mid=(rt->l+rt->r)>>;
if(r<=mid)add(rt->left,l,r,v);
else if(l>=mid+)add(rt->right,l,r,v);
else
{
add(rt->left,l,mid,v);
add(rt->right,mid+,r,v);
}
maintain(rt);
} void set(node *rt,int l,int r,int v)
{
if(l==rt->l&&r==rt->r)
{
rt->ad=v;
rt->flag2=;
pushdown(rt);
return;
}
int mid=(rt->l+rt->r)>>;
if(r<=mid)set(rt->left,l,r,v);
else if(l>=mid+)set(rt->right,l,r,v);
else
{
set(rt->left,l,mid,v);
set(rt->right,mid+,r,v);
}
maintain(rt);
}
int ssum,mma,mmi;
void query(node *rt,int l,int r)
{
if(l==rt->l&&r==rt->r)
{
ssum+=rt->sum;
mma=max(rt->ma,mma);
mmi=min(rt->mi,mmi);
return;
}
int mid=(rt->l+rt->r)>>;
if(r<=mid)query(rt->left,l,r);
else if(l>=mid+)query(rt->right,l,r);
else
{
query(rt->left,l,mid);
query(rt->right,mid+,r);
}
} int main()
{
int n,m,q,cmd,x1,y1,x2,y2,v;
while(scanf("%d%d%d",&n,&m,&q)!=EOF)
{
nonocount=;
for(int i=; i<=n; i++)
build(no+i,,m);
while(q--)
{
scanf("%d",&cmd);
if(cmd==)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
scanf("%d",&v);
for(int i=x1; i<=x2; i++)
add(no+i,y1,y2,v);
}
else if(cmd==)
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
scanf("%d",&v);
for(int i=x1; i<=x2; i++)
set(no+i,y1,y2,v);
}
else
{
int ans=;
mma=-,mmi=;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
for(int i=x1; i<=x2; i++)
{
ssum=;
query(no+i,y1,y2);
ans+=ssum;
}
printf("%d %d %d\n",ans,mmi,mma);
}
}
}
return ;
}