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

UVA - 11992 —— Fast Matrix Operations 【二维线段树转一维】

2016-05-18 21:38 459 查看
http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18697

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#define INF 0x3f3f3f3f
#define left rt<<1
#define right rt<<1|1
using namespace std;

const int MAXN = 1048576 + 5;

struct Node {
int sum, min, max;
Node() {}
Node(int sum, int min, int max):sum(sum), min(min), max(max) {}
};

struct Tree {
Node a[MAXN<<1];
int set[MAXN<<1];
int add[MAXN<<1];
} tree[20];

int r, c;

void pushup(int i, int rt)
{
Node* cur = tree[i].a;
cur[rt].sum = cur[left].sum + cur[right].sum;
cur[rt].max = max(cur[left].max, cur[right].max);
cur[rt].min = min(cur[left].min, cur[right].min);
}

void pushdown(int i, int rt, int w)
{
Tree &cur = tree[i];
  // 优先set,其次add
if(cur.set[rt] != -1) {
cur.set[left] = cur.set[right] = cur.set[rt];

cur.a[left].sum = (w - (w>>1)) * cur.set[rt];
cur.a[right].sum = (w>>1) * cur.set[rt];

cur.a[left].min = cur.a[right].min = cur.a[left].max = cur.a[right].max = cur.set[rt];

cur.add[left] = cur.add[right] = 0;

cur.set[rt] = -1;
}
if(cur.add[rt] != 0) {
cur.add[left] += cur.add[rt];
cur.add[right] += cur.add[rt];

cur.a[left].sum += (w - (w>>1)) * cur.add[rt];
cur.a[right].sum += (w>>1) * cur.add[rt];

cur.a[left].min += cur.add[rt];
cur.a[right].min += cur.add[rt];

cur.a[left].max += cur.add[rt];
cur.a[right].max += cur.add[rt];

cur.add[rt] = 0;
}
}

void add(int ql, int qr, int x, int i, int rt, int l, int r)
{
//    printf("%d %d %d\n", rt, l, r); //

if(ql <= l && r <= qr) {
tree[i].add[rt] += x;
tree[i].a[rt].sum += (r - l + 1) * x;
tree[i].a[rt].max += x;
tree[i].a[rt].min += x;
return;
}
pushdown(i, rt, r - l + 1);
int m = (l + r) >> 1;
if(ql <= m)    add(ql, qr, x, i, left, l, m);
if(qr > m)    add(ql, qr, x, i, right, m+1, r);
pushup(i, rt);
}

void set(int ql, int qr, int x, int i, int rt, int l, int r)
{
if(ql <= l && r <= qr) {
tree[i]
4000
.set[rt] = x;
tree[i].a[rt].sum = (r - l + 1) * x;
tree[i].a[rt].max = tree[i].a[rt].min = x;
tree[i].add[rt] = 0;
return;
}
pushdown(i, rt, r - l + 1);
int m = (l + r) >> 1;
if(ql <= m)    set(ql, qr, x, i, left, l, m);
if(qr > m)    set(ql, qr, x, i, right, m+1, r);
pushup(i, rt);
}

Node query(int ql, int qr, int i, int rt, int l, int r)
{
if(ql <= l && r <= qr) {
Node &cur = tree[i].a[rt];
return    Node(cur.sum, cur.min, cur.max);
}
pushdown(i, rt, r - l + 1);
int m = (l + r) >> 1;
Node ret(0, INF, -1), temp;
if(ql <= m) {
temp = query(ql, qr, i, left, l, m);
ret.sum += temp.sum;
ret.max = max(ret.max, temp.max);
ret.min = min(ret.min, temp.min);
}
if(qr > m) {
temp = query(ql, qr, i, right, m+1, r);
ret.sum += temp.sum;
ret.max = max(ret.max, temp.max);
ret.min = min(ret.min, temp.min);
}
return ret;
}

void build(int i, int rt, int l, int r)
{
tree[i].add[rt] = 0;
tree[i].set[rt] = -1;
if(l == r) {
tree[i].a[rt].sum = tree[i].a[rt].min = tree[i].a[rt].max = 0;
return;
}
int m = (l + r) >> 1;
build(i, left, l, m);
build(i, right, m+1, r);
pushup(i, rt);
}

int main ()
{
int m, type, x1, y1, x2, y2, v;
while(scanf("%d%d%d", &r, &c, &m) != EOF) {

for(int i=0; i<r; i++) {
build(i, 1, 1, c);
}
while(m--) {
scanf("%d%d%d%d%d", &type, &x1, &y1, &x2, &y2);
x1--;
x2--;

if(type == 1) {
scanf("%d", &v);
for(int i=x1; i<=x2; i++) {
add(y1, y2, v, i, 1, 1, c);
}
} else if(type == 2) {
scanf("%d", &v);
for(int i=x1; i<=x2; i++) {
set(y1, y2, v, i, 1, 1, c);
}
} else {
Node ans(0, INF, -1), temp;
for(int i=x1; i<=x2; i++) {
temp = query(y1, y2, i, 1, 1, c);
ans.sum += temp.sum;
ans.max = max(ans.max, temp.max);
ans.min = min(ans.min, temp.min);
}
printf("%d %d %d\n", ans.sum, ans.min, ans.max);
}
}
}
return 0;
}


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