要wa死了,书上的代码没太看懂,就按照自己的想法写的,其中掺杂了书上的一些代码居然不对,唉……
#include <iostream>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <vector>
#include <cstring>
#include <algorithm>
#define INF 0x7fffffff
#define N 10010
#define M 1000010
#define LL long long
#define mod 95041567
using namespace std;
struct node{
int MAX, MIN, ADD, SET, SUM;
};
node p;
node G[22][M << 2];
int cnt;
void pushdown(int i, int rt, int L, int R){
int lc = rt << 1, rc = (rt << 1) | 1, mid = (R - L) / 2 + L;
if(G[i][rt].SET != INF){
G[i][lc].SET = G[i][rc].SET = G[i][rt].SET;
G[i][rt].SUM = (R - L + 1) * G[i][rt].SET;
G[i][rc].SUM = (R - mid) * G[i][rt].SET;
G[i][lc].SUM = (mid + 1 - L) * G[i][rt].SET;
G[i][rt].MIN = G[i][rc].MIN = G[i][lc].MIN = G[i][rt].SET;
G[i][rt].MAX = G[i][rc].MAX = G[i][lc].MAX = G[i][rt].SET;
G[i][rt].SET = INF;
G[i][rc].ADD = G[i][lc].ADD = 0;
}
if(G[i][rt].ADD){
G[i][lc].MIN += G[i][rt].ADD;
G[i][lc].MAX += G[i][rt].ADD;
G[i][lc].ADD += G[i][rt].ADD;
G[i][lc].SUM += G[i][rt].ADD * (mid + 1 - L);
G[i][rc].MIN += G[i][rt].ADD;
G[i][rc].MAX += G[i][rt].ADD;
G[i][rc].ADD += G[i][rt].ADD;
G[i][rc].SUM += G[i][rt].ADD * (R - mid);
G[i][rt].ADD = 0;
}
}
void maintain(int i, int rt, int L, int R){
if(R <= L) return;
int lc = rt << 1, rc = (rt << 1) | 1;
G[i][rt].SUM = G[i][lc].SUM + G[i][rc].SUM;
G[i][rt].MIN = min(G[i][lc].MIN, G[i][rc].MIN);
G[i][rt].MAX = max(G[i][lc].MAX, G[i][rc].MAX);
G[i][rt].SUM += G[i][rt].ADD * (R - L + 1);
G[i][rt].MIN += G[i][rt].ADD;
G[i][rt].MAX += G[i][rt].ADD;
}
void update(int i,int f, int rt, int L, int R, int y1, int y2, int v){
if(y1 == L && y2 == R){
if(f){
G[i][rt].MAX = G[i][rt].MIN = G[i][rt].SET = v;
G[i][rt].SUM = v * (R - L + 1);
G[i][rt].ADD = 0;
}
else{
G[i][rt].ADD += v;
G[i][rt].MIN += v;
G[i][rt].MAX += v;
G[i][rt].SUM += (R - L + 1) * v;
}
return;
}
pushdown(i, rt, L, R);
int lc = rt << 1, rc = (rt << 1) | 1, mid = (R - L) / 2 + L;
if(y2 <= mid) update(i, f, lc, L, mid, y1, y2, v);
else if(y1 > mid) update(i, f, rc, mid + 1, R, y1, y2, v);
else{
update(i, f, lc, L, mid, y1, mid, v);
update(i, f, rc, mid + 1, R, mid + 1, y2, v);
}
maintain(i, rt, L, R);
}
void query(int i, int rt, int L, int R, int y1, int y2){
if(L == y1 && R == y2){
p.MAX = max(p.MAX, G[i][rt].MAX);
p.MIN = min(p.MIN, G[i][rt].MIN);
p.SUM += G[i][rt].SUM;
return;
}
pushdown(i, rt, L, R);
int lc = rt << 1, rc = (rt << 1) | 1, mid = (R - L) / 2 + L;
if(y1 > mid) query(i, rc, mid + 1, R, y1, y2);
else if(y2 <= mid) query(i, lc, L, mid, y1, y2);
else{
query(i, rc, mid + 1, R, mid + 1, y2);
query(i, lc, L, mid, y1 ,mid);
}
maintain(i, rt, L, R);
}
int main()
{
int r, c, q;
//freopen("in.txt","r",stdin);
while(scanf("%d %d %d", &r, &c, &q) != EOF){
for(int i = 0; i < r; ++i)
for(int j = c << 2; j >= 0; -- j)
G[i][j].MAX = G[i][j].MIN = G[i][j].ADD = G[i][j].SUM = 0, G[i][j].SET = INF;
int f, x1, y1, x2, y2, v;
for(int i = 0; i < q; ++ i){
cnt = i;
scanf("%d %d %d %d %d", &f, &x1, &y1, &x2, &y2);
-- f, -- x1, -- x2, -- y1, -- y2;
if(f <= 1){
scanf("%d", &v);
for(int j = x1; j <= x2; ++ j) update(j, f, 1, 0, c - 1, y1, y2, v);
}
else {
p.SUM = p.MAX = 0, p.MIN = INF;
for(int j = x1; j <= x2; ++ j) query(j, 1, 0, c - 1, y1, y2);
printf("%d %d %d\n", p.SUM, p.MIN, p.MAX);
}
}
}
return 0;
}
11992 - Fast Matrix Operations
最新推荐文章于 2021-03-16 19:04:13 发布