标签:hang 技术 png tree c++ res strong UNC 高度
题意
给一个 \(n\times m\) 的矩形,代表对应位置方块的数目,现在进行 \(k\) 次激光攻击,每次激光攻击会在高度 \(h\) 处从 \(N,S,W,E\) 四个方向中的一个向对面发射激光,若命中一个块,则改方块消失,每次激光最多消灭 \(r\) 个方块。
攻击结束后,方块会掉落。问最后在 \(p \times p\) 的矩形内,最多有多少个方块
\(1 \le n*m \le 1e6\) , \(1 \le r \le 10\) , \(1\le k\le 3e5\) , \(1 \le p \le min(n,m,10)\)
思路
用线段树模拟即可,每次找区间内第一个大于等于某个值的元素,或者最后一个大于等于某个元素(高度)的值,
最后做一个二维前缀和
#include<bits/stdc++.h>
using namespace std;
#define lo (o << 1)
#define ro (o << 1 | 1)
#define mid (l + r >> 1)
#define what(x) cerr << #x << " is " << x << endl;
#define getall(x,ed) cerr << #x << ": \t";debug(x,ed);
template<typename T>
void debug(T begin, T ed) {
for (T i = begin;i != ed;i++)cout << *i << ‘\t‘;cout << ‘\n‘;
}
typedef long long ll;
int n, m, r, k, p;
vector<vector<int>>mp, RTree, CTree;
vector<vector<ll>>qzh;
void build(vector<int>& Tree, int o, int l, int r, int type, int idx) {
if (l == r) {
if (type == 0) {
Tree[o] = mp[idx][l];
}
else {
Tree[o] = mp[l][idx];
}
return;
}
build(Tree, lo, l, mid, type, idx);build(Tree, ro, mid + 1, r, type, idx);
Tree[o] = max(Tree[lo], Tree[ro]);
}
int query_first(vector<int>& Tree, int L, int R, int tar, int o, int l, int r) {
if(l == r){
if(Tree[o] >= tar)return l;
else return -1;
}
if (L <= l and r <= R) {
if(Tree[o] < tar) return -1;
}
int ans = -1;
if (L <= mid) ans = query_first(Tree, L, R, tar, lo, l, mid);
if (ans != -1)return ans;
if (R > mid)ans = query_first(Tree, L, R, tar, ro, mid + 1, r);
return ans;
}
int query_last(vector<int>& Tree, int L, int R, int tar, int o, int l, int r) {
if (l == r) {
if (Tree[o] >= tar)return l;
else return -1;
}
if (L <= l and r <= R) {
if (Tree[o] < tar) return -1;
}
int ans = -1;
if (R > mid)ans = query_last(Tree, L, R, tar, ro, mid + 1, r);
if (ans != -1)return ans;
if (L <= mid) ans = query_last(Tree, L, R, tar, lo, l, mid);
return ans;
}
void updtTree(vector<int>& Tree, int pos, int o, int l, int r) {
if (l == r) {
Tree[o]--;
return;
}
if (pos <= mid)updtTree(Tree, pos, lo, l, mid);
else updtTree(Tree, pos, ro, mid + 1, r);
Tree[o] = max(Tree[lo], Tree[ro]);
}
void modify(int r, int c) {
updtTree(RTree[r], c, 1, 1, m);
updtTree(CTree[c], r, 1, 1, n);
mp[r][c]--;
}
int main() {
#ifdef ONLINE_JUDGE
freopen("c.in", "r", stdin);
//freopen("out.txt","w",stdout);
#endif
scanf("%d%d%d%d%d", &n, &m, &r, &k, &p);
mp.resize(n + 1, vector<int>(m + 1, 0));
for (int i = 1;i <= n;i++)for (int j = 1;j <= m;j++)scanf("%d", &mp[i][j]);
RTree.resize(n + 1, vector<int>((m + 1) << 2, 0));
CTree.resize(m + 1, vector<int>((n + 1) << 2, 0));
for (int i = 1;i <= n;i++)build(RTree[i], 1, 1, m, 0, i);
for (int i = 1;i <= m;i++)build(CTree[i], 1, 1, n, 1, i);
//puts("build");
while (k--) {
char dir[2];int pos, h;
scanf("%s%d%d", dir, &pos, &h);
if (*dir == ‘N‘) {
int L = 1, R = n;
for (int k = 1;k <= r;k++) {
int p = query_first(CTree[pos], L, R, h, 1, 1, n);
if (p == -1)break;
modify(p, pos);
L = p + 1;
}
}
else if (*dir == ‘S‘) {
int L = 1, R = n;
for (int k = 1;k <= r;k++) {
int p = query_last(CTree[pos], L, R, h, 1, 1, n);
if (p == -1)break;
modify(p, pos);
R = p - 1;
}
}
else if (*dir == ‘W‘) {
int L = 1, R = m;
for (int k = 1;k <= r;k++) {
int p = query_first(RTree[pos], L, R, h, 1, 1, m);
if (p == -1)break;
modify(pos, p);
L = p + 1;
}
}
else if (*dir == ‘E‘) {
int L = 1, R = m;
for (int k = 1;k <= r;k++) {
//what(pos);what(h);
int p = query_last(RTree[pos], L, R, h, 1, 1, m);
if (p == -1)break;
modify(pos, p);
R = p - 1;
}
}
}
//puts("ok");
qzh.resize(n + 1, vector<ll>(m + 1, 0));
// for(int i = 1;i <= n;i++){
// for(int j = 1;j <= m;j++){
// cout << mp[i][j] << " ";
// }cout << ‘\n‘;
// }
//getall(mp[1].begin() + 1, mp[1].end());
ll ans = 0;
for (int i = 1;i <= n;i++) {
for (int j = 1;j <= m;j++) {
qzh[i][j] = mp[i][j] + qzh[i - 1][j] + qzh[i][j - 1] - qzh[i - 1][j - 1];
if (i >= p and j >= p) {
ans = max(ans, qzh[i][j] - qzh[i - p][j] - qzh[i][j - p] + qzh[i - p][j - p]);
}
}
}
printf("%lld\n", ans);;
}
标签:hang 技术 png tree c++ res strong UNC 高度
原文地址:https://www.cnblogs.com/sduwh/p/14516179.html