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

UVA 11992 Fast Matrix Operations (降维)

2015-09-07 23:02 253 查看
题意:对一个矩阵进行子矩阵操作。

元素最多有1e6个,树套树不好开(我不会),把二维坐标化成一维的,一个子矩阵操作分解成多条线段的操作。

一次操作的复杂度是RlogC,很容易找到极端的数据(OJ上实测没有),如果判断一下然后启发式建树复杂度是min(RlogC,ClogR)。

代码中结点没有保存l和r,而且询问是保存在全局变量中,这样做比较省空间。但是也有缺点,比如推区间结点数量的时候会麻烦一点。

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1e6+1;
int R,C;

#define lid (id<<1)
#define rid (id<<1|1)
struct Seg
{
int add,setv;
int Max,Min,sum;
}tr[maxn<<2];

#define OP1(id,val)\
tr[id].add += val; tr[id].Max += val; tr[id].Min += val; tr[id].sum += (r-l+1)*val;
#define OP2(id,val)\
tr[id].Max = tr[id].setv = tr[id].Min = val; tr[id].add = 0; tr[id].sum = val*(r-l+1);

inline void push_down(int id,int l,int r)
{
int lc = lid, rc = rid, mid = (l+r)>>1;
if(tr[id].setv>=0){
int &t = tr[id].setv;
swap(r,mid);
OP2(lc,t);
swap(l,r); l++; swap(mid,r);
OP2(rc,t);
l--; swap(mid,l);
t = -1;
}
if(tr[id].add>0){
int &t = tr[id].add;
swap(r,mid);
OP1(lc,t);
swap(l,r); l++; swap(mid,r);
OP1(rc,t);
l--; swap(mid,l);
t = 0;
}
}

inline void maintain(int id)
{
int lc = lid, rc = rid;
tr[id].sum = tr[lc].sum + tr[rc].sum;
tr[id].Max = max(tr[lc].Max,tr[rc].Max);
tr[id].Min = min(tr[lc].Min,tr[rc].Min);
}

int ql,qr,val;
void add1D(int l = 0,int r = R*C-1,int id = 1)
{
if(ql<=l&&r<=qr) { OP1(id,val) return; }
int mid = (l+r)>>1, lc = lid, rc = rid;
push_down(id,l,r);
if(ql<=mid) add1D(l,mid,lc);
if(qr>mid) add1D(mid+1,r,rc);
maintain(id);
}

void set1D(int l = 0,int r = R*C-1,int id = 1)
{
if(ql<=l&&r<=qr) { OP2(id,val) return; }
int mid = (l+r)>>1, lc = lid, rc = rid;
push_down(id,l,r);
if(ql<=mid) set1D(l,mid,lc);
if(qr>mid) set1D(mid+1,r,rc);
maintain(id);
}

int queryMax1D(int l = 0,int r = R*C-1,int id = 1)
{
if(ql<=l&&r<=qr) { return tr[id].Max; }
int mid = (l+r)>>1, lc = lid, rc = rid;
push_down(id,l,r);
int ret = 0;
if(ql<=mid) ret = max(ret,queryMax1D(l,mid,lc));
if(qr>mid) ret = max(ret,queryMax1D(mid+1,r,rc));
return ret;
}

const int INF = 0x3f3f3f3f;

int queryMin1D(int l = 0,int r = R*C-1,int id = 1)
{
if(ql<=l&&r<=qr) { return tr[id].Min; }
int mid = (l+r)>>1, lc = lid, rc = rid;
push_down(id,l,r);
int ret = INF;
if(ql<=mid) ret = min(ret,queryMin1D(l,mid,lc));
if(qr>mid) ret = min(ret,queryMin1D(mid+1,r,rc));
return ret;
}

int querySum1D(int l = 0,int r = R*C-1,int id = 1)
{
if(ql<=l&&r<=qr) { return tr[id].sum; }
int mid = (l+r)>>1, lc = lid, rc = rid;
push_down(id,l,r);
int ret = 0;
if(ql<=mid) ret += querySum1D(l,mid,lc);
if(qr>mid) ret += querySum1D(mid+1,r,rc);
return ret;
}

//[0,r)
void add2D(int x1,int y1,int x2,int y2,int v)
{
val = v;
int st = x1*C+y1, len = y2-y1;
for(int x = x1; x <= x2; x++){
ql = st; qr = st+len;
add1D();
st += C;
}
}

void set2D(int x1,int y1,int x2,int y2,int v)
{
val = v;
int st = x1*C+y1, len = y2-y1;
for(int x = x1; x <= x2; x++){
ql = st; qr = st+len;
set1D();
st += C;
}
}

int querySum2D(int x1,int y1,int x2,int y2)
{
int ret = 0;
int st = x1*C+y1, len = y2-y1;
for(int x = x1; x <= x2; x++){
ql = st; qr = st+len;
ret += querySum1D();
st += C;
}
return ret;
}

int queryMax2D(int x1,int y1,int x2,int y2)
{
int ret = 0;
int st = x1*C+y1, len = y2-y1;
for(int x = x1; x <= x2; x++){
ql = st; qr = st+len;
ret = max(ret,queryMax1D());
st += C;
}
return ret;
}

int queryMin2D(int x1,int y1,int x2,int y2)
{
int ret = INF;
int st = x1*C+y1, len = y2-y1;
for(int x = x1; x <= x2; x++){
ql = st; qr = st+len;
ret = min(ret,queryMin1D());
st += C;
}
return ret;
}

int main()
{
//freopen("in.txt","r",stdin);
int m;
while(~scanf("%d%d%d",&R,&C,&m)){
ql = 0; qr = R*C-1; val = 0;
set1D();
while(m--){
int op,x1,y1,x2,y2; scanf("%d%d%d%d%d",&op,&x1,&y1,&x2,&y2);
if(op == 1){
int v; scanf("%d",&v);
add2D(x1-1,y1-1,x2-1,y2-1,v);
}else if(op == 2){
int v; scanf("%d",&v);
set2D(x1-1,y1-1,x2-1,y2-1,v);
}else {
x1--;x2--;y1--;y2--;
printf("%d %d %d\n",querySum2D(x1,y1,x2,y2),queryMin2D(x1,y1,x2,y2),queryMax2D(x1,y1,x2,y2));
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: