【题目大意】
裸题,不解释,上模板。
比较省内存的写法:
/* HDU 4819 */
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<cctype>
#include<string>
#include<algorithm>
#include<iostream>
#include<ctime>
#include<map>
#include<set>
using namespace std;
#define MP(x,y) make_pair((x),(y))
#define PB(x) push_back(x)
typedef __int64 LL;
//typedef unsigned __int64 ULL;
/* ****************** */
const int INF = 1000111222;
const double INFF = 1e100;
const double eps = 1e-8;
const LL mod = 10000000007LL;
const int NN = 810;
const int MM = 400010;
/* ****************** */
int m_a[NN*2][NN*2];
int m_i[NN*2][NN*2];
int ans_max, ans_min;
int X1, Y1, X2, Y2, X, Y;
//为了函数的参数不过于冗杂,我把修改和查询的变量改为全局的
int col; //单点修改值,为了模板的移植性,把这个设置为全局变量
inline int MID(int x,int y)
{
return (x + y) >> 1;
}
inline int loc(int l,int r)
{
return (l + r) | !(l==r);
}
inline int ls(int l,int r)
{
return loc(l, MID(l, r));
}
inline int rs(int l,int r)
{
return loc(MID(l, r) + 1, r);
}
void update1D(int st,int en,int l,int r)
{
int R1 = loc(st, en);
int R2 = loc(l, r);
if (l == r)
{
if (st == en)
{
//这个是一个点,直接修改
m_a[R1][R2] = m_i[R1][R2] = col;
return;
}
//虽然这个在辅线段树中是一个点,但是在主线段树中不是一个点
//所幸的是,主线段中对应的下方节点是修改好了的,所以利用主线段树修改
int R1_lson = ls(st, en);
int R1_rson = rs(st, en);
m_a[R1][R2] = max(m_a[R1_lson][R2], m_a[R1_rson][R2]);
m_i[R1][R2] = min(m_i[R1_lson][R2], m_i[R1_rson][R2]);
}
else
{
//这部分和一维线段树的基础操作类似
int mid = MID(l, r);
if (Y <= mid)
update1D(st, en, l, mid);
else
update1D(st, en, mid + 1, r);
int R2_lson = ls(l, r);
int R2_rson = rs(l, r);
m_a[R1][R2] = max(m_a[R1][R2_lson], m_a[R1][R2_rson]);
m_i[R1][R2] = min(m_i[R1][R2_lson], m_i[R1][R2_rson]);
}
}
void update2D(int st,int en,int l,int r)
{
if (st == en)
{
update1D(st, en, l, r);
}
else
{
int mid = MID(st, en);
if (X <= mid)
update2D(st, mid, l, r);
else
update2D(mid+1, en, l, r);
update1D(st, en, l, r);
}
}
void query1D(int st,int en,int l,int r)
{
if (Y1 <= l && r <= Y2)
{
int R1 = loc(st, en);
int R2 = loc(l, r);
ans_max = max(ans_max, m_a[R1][R2]);
ans_min = min(ans_min, m_i[R1][R2]);
}
else
{
int mid = MID(l, r);
if (Y1 <= mid)
query1D(st, en, l, mid);
if (Y2 >= mid + 1)
query1D(st, en, mid + 1, r);
}
}
void query2D(int st,int en,int l,int r)
{
if (X1 <= st && en <= X2)
{
query1D(st, en, l, r);
}
else
{
int mid = MID(st, en);
if (X1 <= mid)
query2D(st, mid, l, r);
if (X2 >= mid + 1)
query2D(mid + 1, en, l, r);
}
}
int main()
{
int cas, ee = 0;
int i, j, n, m, x, y, z;
scanf("%d", &cas);
while (cas--)
{
printf("Case #%d:\n", ++ee);
scanf("%d", &n);
for (i = 1; i <= n; i ++)
for (j = 1; j <= n; j ++)
{
scanf("%d", &col);
X = i;
Y = j;
update2D(1, n, 1, n);
}
scanf("%d", &m);
for (i = 0; i < m; i ++)
{
scanf("%d%d%d", &x, &y, &z);
X1 = max(1, x - z/2);
X2 = min(n, x + z/2);
Y1 = max(1, y - z/2);
Y2 = min(n, y + z/2);
ans_max = -INF;
ans_min = INF;
query2D(1, n, 1, n);
// cout<<"max=="<<ans_max<<endl;
// cout<<"min=="<<ans_min<<endl;
col = (ans_max + ans_min)/2;
printf("%d\n", col);
X = x;
Y = y;
update2D(1, n, 1, n);
}
}
return 0;
}
一般的写法:
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#include<cmath>
#include<cctype>
#include<string>
#include<algorithm>
#include<iostream>
#include<ctime>
#include<map>
#include<set>
using namespace std;
#define MP(x,y) make_pair((x),(y))
#define PB(x) push_back(x)
typedef __int64 LL;
//typedef unsigned __int64 ULL;
/* ****************** */
const int INF = 1000111222;
const double INFF = 1e100;
const double eps = 1e-8;
const LL mod = 10000000007LL;
const int NN = 810;
const int MM = 400010;
/* ****************** */
int m_a[NN*4][NN*4];
int m_i[NN*4][NN*4];
int ans_max, ans_min;
int X1, Y1, X2, Y2, X, Y;
bool leaf;
//为了函数的参数不过于冗杂,我把修改和查询的变量改为全局的
int col; //单点修改值,为了模板的移植性,把这个设置为全局变量
inline int MID(int x,int y)
{
return (x + y) >> 1;
}
void update1D(int R1,int R2,int l,int r)
{
if (l == r)
{
if (leaf)
{
//这个是一个点,直接修改
m_a[R1][R2] = m_i[R1][R2] = col;
return;
}
//虽然这个在辅线段树中是一个点,但是在主线段树中不是一个点
//所幸的是,主线段中对应的下方节点是修改好了的,所以利用主线段树修改
m_a[R1][R2] = max(m_a[R1<<1][R2], m_a[R1<<1|1][R2]);
m_i[R1][R2] = min(m_i[R1<<1][R2], m_i[R1<<1|1][R2]);
}
else
{
//这部分和一维线段树的基础操作类似
int mid = MID(l, r);
if (Y <= mid)
update1D(R1, R2<<1, l, mid);
else
update1D(R1, R2<<1|1, mid + 1, r);
m_a[R1][R2] = max(m_a[R1][R2<<1], m_a[R1][R2<<1|1]);
m_i[R1][R2] = min(m_i[R1][R2<<1], m_i[R1][R2<<1|1]);
}
}
void update2D(int R1,int st,int en,int l,int r)
{
if (st == en)
{
leaf = true;
update1D(R1, 1, l, r);
}
else
{
int mid = MID(st, en);
if (X <= mid)
update2D(R1<<1, st, mid, l, r);
else
update2D(R1<<1|1, mid+1, en, l, r);
leaf = false;
update1D(R1, 1, l, r);
}
}
void query1D(int R1,int R2,int l,int r)
{
if (Y1 <= l && r <= Y2)
{
ans_max = max(ans_max, m_a[R1][R2]);
ans_min = min(ans_min, m_i[R1][R2]);
}
else
{
int mid = MID(l, r);
if (Y1 <= mid)
query1D(R1, R2<<1, l, mid);
if (Y2 >= mid + 1)
query1D(R1, R2<<1|1, mid + 1, r);
}
}
void query2D(int R1,int st,int en,int l,int r)
{
if (X1 <= st && en <= X2)
{
query1D(R1, 1, l, r);
}
else
{
int mid = MID(st, en);
if (X1 <= mid)
query2D(R1<<1, st, mid, l, r);
if (X2 >= mid + 1)
query2D(R1<<1|1, mid + 1, en, l, r);
}
}
int main()
{
int cas, ee = 0;
int i, j, n, m, x, y, z;
scanf("%d", &cas);
while (cas--)
{
printf("Case #%d:\n", ++ee);
scanf("%d", &n);
for (i = 1; i <= n; i ++)
for (j = 1; j <= n; j ++)
{
scanf("%d", &col);
X = i;
Y = j;
update2D(1, 1, n, 1, n);
}
scanf("%d", &m);
for (i = 0; i < m; i ++)
{
scanf("%d%d%d", &x, &y, &z);
X1 = max(1, x - z/2);
X2 = min(n, x + z/2);
Y1 = max(1, y - z/2);
Y2 = min(n, y + z/2);
ans_max = -INF;
ans_min = INF;
query2D(1, 1, n, 1, n);
// cout<<"max=="<<ans_max<<endl;
// cout<<"min=="<<ans_min<<endl;
col = (ans_max + ans_min)/2;
printf("%d\n", col);
X = x;
Y = y;
update2D(1, 1, n, 1, n);
}
}
return 0;
}