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

【UVa】11992 Fast Matrix Operations

2012-06-30 09:59 411 查看
#include<cstdio>
#define INF 0x7FFFFFFF
#define MAXN 1000010
struct node
{
int cnt,son[4],kind[4];
int big,small,sum,add,cover;
};
node tree[MAXN<<2];
int size,SUM,BIG,SMALL;
inline int MAX(int x,int y)
{
return x>y?x:y;
}
inline int MIN(int x,int y)
{
return x>y?y:x;
}
void Build(int x1,int x2,int y1,int y2,int rt)
{
tree[rt].cnt=0;
tree[rt].big=tree[rt].small=tree[rt].sum=tree[rt].add=tree[rt].cover=0;
if(x1!=x2||y1!=y2)
{
int i,mid1=(x1+x2)>>1,mid2=(y1+y2)>>1;
if(x1<=mid1)
{
if(y1<=mid2)
{
tree[rt].kind[tree[rt].cnt]=1;
tree[rt].son[tree[rt].cnt++]=size++;
}
if(y2>mid2)
{
tree[rt].kind[tree[rt].cnt]=2;
tree[rt].son[tree[rt].cnt++]=size++;
}
}
if(x2>mid1)
{
if(y1<=mid2)
{
tree[rt].kind[tree[rt].cnt]=3;
tree[rt].son[tree[rt].cnt++]=size++;
}
if(y2>mid2)
{
tree[rt].kind[tree[rt].cnt]=4;
tree[rt].son[tree[rt].cnt++]=size++;
}
}
for(i=0;i<tree[rt].cnt;i++)
{
if(tree[rt].kind[i]==1)
Build(x1,mid1,y1,mid2,tree[rt].son[i]);
else if(tree[rt].kind[i]==2)
Build(x1,mid1,mid2+1,y2,tree[rt].son[i]);
else if(tree[rt].kind[i]==3)
Build(mid1+1,x2,y1,mid2,tree[rt].son[i]);
else
Build(mid1+1,x2,mid2+1,y2,tree[rt].son[i]);
}
}
}
void PushDown(int x1,int x2,int mid1,int y1,int y2,int mid2,int rt)
{
int i;
if(tree[rt].cover)
{
for(i=0;i<tree[rt].cnt;i++)
{
if(tree[rt].kind[i]==1)
tree[tree[rt].son[i]].sum=(mid1-x1+1)*(mid2-y1+1)*tree[rt].cover;
else if(tree[rt].kind[i]==2)
tree[tree[rt].son[i]].sum=(mid1-x1+1)*(y2-mid2)*tree[rt].cover;
else if(tree[rt].kind[i]==3)
tree[tree[rt].son[i]].sum=(x2-mid1)*(mid2-y1+1)*tree[rt].cover;
else
tree[tree[rt].son[i]].sum=(x2-mid1)*(y2-mid2)*tree[rt].cover;
tree[tree[rt].son[i]].add=0;
tree[tree[rt].son[i]].cover=tree[tree[rt].son[i]].big=tree[tree[rt].son[i]].small=tree[rt].cover;
}
tree[rt].cover=0;
}
if(tree[rt].add)
{
for(i=0;i<tree[rt].cnt;i++)
{
if(tree[rt].kind[i]==1)
tree[tree[rt].son[i]].sum+=(mid1-x1+1)*(mid2-y1+1)*tree[rt].add;
else if(tree[rt].kind[i]==2)
tree[tree[rt].son[i]].sum+=(mid1-x1+1)*(y2-mid2)*tree[rt].add;
else if(tree[rt].kind[i]==3)
tree[tree[rt].son[i]].sum+=(x2-mid1)*(mid2-y1+1)*tree[rt].add;
else
tree[tree[rt].son[i]].sum+=(x2-mid1)*(y2-mid2)*tree[rt].add;
tree[tree[rt].son[i]].add+=tree[rt].add;
tree[tree[rt].son[i]].big+=tree[rt].add;
tree[tree[rt].son[i]].small+=tree[rt].add;
}
tree[rt].add=0;
}
}
void PushUp(int rt)
{
int i;
tree[rt].big=tree[rt].sum=0;
tree[rt].small=INF;
for(i=0;i<tree[rt].cnt;i++)
{
tree[rt].sum+=tree[tree[rt].son[i]].sum;
tree[rt].big=MAX(tree[rt].big,tree[tree[rt].son[i]].big);
tree[rt].small=MIN(tree[rt].small,tree[tree[rt].son[i]].small);
}
}
void Add(int x1,int x2,int y1,int y2,int val,int a,int b,int c,int d,int rt)
{
if(x1<=a&&b<=x2&&y1<=c&&d<=y2)
{
tree[rt].add+=val;
tree[rt].big+=val;
tree[rt].small+=val;
tree[rt].sum+=val*(b-a+1)*(d-c+1);
}
else
{
int mid1=(a+b)>>1,mid2=(c+d)>>1,i=0;
PushDown(a,b,mid1,c,d,mid2,rt);
if(x1<=mid1)
{
if(y1<=mid2)
{
for(;tree[rt].kind[i]!=1&&i<tree[rt].cnt;i++);
if(tree[rt].kind[i]==1)
Add(x1,x2,y1,y2,val,a,mid1,c,mid2,tree[rt].son[i]);
}
if(y2>mid2)
{
for(;tree[rt].kind[i]!=2&&i<tree[rt].cnt;i++);
if(tree[rt].kind[i]==2)
Add(x1,x2,y1,y2,val,a,mid1,mid2+1,d,tree[rt].son[i]);
}
}
if(x2>mid1)
{
if(y1<=mid2)
{
for(;tree[rt].kind[i]!=3&&i<tree[rt].cnt;i++);
if(tree[rt].kind[i]==3)
Add(x1,x2,y1,y2,val,mid1+1,b,c,mid2,tree[rt].son[i]);
}
if(y2>mid2)
{
for(;tree[rt].kind[i]!=4&&i<tree[rt].cnt;i++);
if(tree[rt].kind[i]==4)
Add(x1,x2,y1,y2,val,mid1+1,b,mid2+1,d,tree[rt].son[i]);
}
}
PushUp(rt);
}
}
void Cover(int x1,int x2,int y1,int y2,int val,int a,int b,int c,int d,int rt)
{
if(x1<=a&&b<=x2&&y1<=c&&d<=y2)
{
tree[rt].add=0;
tree[rt].cover=tree[rt].big=tree[rt].small=val;
tree[rt].sum=val*(b-a+1)*(d-c+1);
}
else
{
int mid1=(a+b)>>1,mid2=(c+d)>>1,i=0;
PushDown(a,b,mid1,c,d,mid2,rt);
if(x1<=mid1)
{
if(y1<=mid2)
{
for(;tree[rt].kind[i]!=1&&i<tree[rt].cnt;i++);
if(tree[rt].kind[i]==1)
Cover(x1,x2,y1,y2,val,a,mid1,c,mid2,tree[rt].son[i]);
}
if(y2>mid2)
{
for(;tree[rt].kind[i]!=2&&i<tree[rt].cnt;i++);
if(tree[rt].kind[i]==2)
Cover(x1,x2,y1,y2,val,a,mid1,mid2+1,d,tree[rt].son[i]);
}
}
if(x2>mid1)
{
if(y1<=mid2)
{
for(;tree[rt].kind[i]!=3&&i<tree[rt].cnt;i++);
if(tree[rt].kind[i]==3)
Cover(x1,x2,y1,y2,val,mid1+1,b,c,mid2,tree[rt].son[i]);
}
if(y2>mid2)
{
for(;tree[rt].kind[i]!=4&&i<tree[rt].cnt;i++);
if(tree[rt].kind[i]==4)
Cover(x1,x2,y1,y2,val,mid1+1,b,mid2+1,d,tree[rt].son[i]);
}
}
PushUp(rt);
}
}
void Query(int x1,int x2,int y1,int y2,int a,int b,int c,int d,int rt)
{
if(x1<=a&&b<=x2&&y1<=c&&d<=y2)
{
SUM+=tree[rt].sum;
BIG=MAX(BIG,tree[rt].big);
SMALL=MIN(SMALL,tree[rt].small);
}
else
{
int mid1=(a+b)>>1,mid2=(c+d)>>1,i=0;
PushDown(a,b,mid1,c,d,mid2,rt);
if(x1<=mid1)
{
if(y1<=mid2)
{
for(;tree[rt].kind[i]!=1&&i<tree[rt].cnt;i++);
if(tree[rt].kind[i]==1)
Query(x1,x2,y1,y2,a,mid1,c,mid2,tree[rt].son[i]);
}
if(y2>mid2)
{
for(;tree[rt].kind[i]!=2&&i<tree[rt].cnt;i++);
if(tree[rt].kind[i]==2)
Query(x1,x2,y1,y2,a,mid1,mid2+1,d,tree[rt].son[i]);
}
}
if(x2>mid1)
{
if(y1<=mid2)
{
for(;tree[rt].kind[i]!=3&&i<tree[rt].cnt;i++);
if(tree[rt].kind[i]==3)
Query(x1,x2,y1,y2,mid1+1,b,c,mid2,tree[rt].son[i]);
}
if(y2>mid2)
{
for(;tree[rt].kind[i]!=4&&i<tree[rt].cnt;i++);
if(tree[rt].kind[i]==4)
Query(x1,x2,y1,y2,mid1+1,b,mid2+1,d,tree[rt].son[i]);
}
}
}
}
int main()
{
int n,m,q;
int x1,y1,x2,y2,val,flag;
while(~scanf("%d%d%d",&n,&m,&q))
{
size=2;
Build(1,n,1,m,1);
while(q--)
{
scanf("%d%d%d%d%d",&flag,&x1,&y1,&x2,&y2);
if(flag==1)
{
scanf("%d",&val);
Add(x1,x2,y1,y2,val,1,n,1,m,1);
}
else if(flag==2)
{
scanf("%d",&val);
Cover(x1,x2,y1,y2,val,1,n,1,m,1);
}
else
{
SUM=BIG=0;
SMALL=INF;
Query(x1,x2,y1,y2,1,n,1,m,1);
printf("%d %d %d\n",SUM,SMALL,BIG);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: