k个树状数组维护差分 subtask4,5有8个WA 求调
查看原帖
k个树状数组维护差分 subtask4,5有8个WA 求调
792364
hzx198楼主2024/9/22 19:27
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

constexpr ll N = 2e5 + 5;

struct op { // operate, 表示一次移动
  char c;
  ll a, b;
} op[N];

ll n, m, q, k, x, y; // x, y 表示当前坐标

char mp[505][505]; // 地图
void move(char c, ll a) { // 移动
  if (c == 'U') x = max(x - a, 1ll);
  else if (c == 'D') x = min(x + a, n);
  else if (c == 'L') y = max(y - a, 1ll);
  else if (c == 'R') y = min(y + a, m);
}
char change(char c, ll n) { // 返回 c 字符修改 n 次后的结果
  if (c == 'U') return n & 1 ? 'D' : 'U';
  else if (c == 'D') return n & 1 ? 'U' : 'D';
  else if (c == 'L') return n & 1 ? 'R' : 'L';
  else if (c == 'R') return n & 1 ? 'L' : 'R';
}

ll tree[N][21]; // 树状数组, 维护修改次数的差分, 树状数组的下标即为原序列下标模 k 的余数 (若整除则为 k)
ll lowbit(ll x) { return (-x) & x; }
// add 和 query 适用于单个树状数组
void add(ll id, ll i, ll x) { // 将下标为 id 的树状数组的第 i 个元素加上 x
  while (i <= N) {
    tree[id][i] += x;
    i += lowbit(i);
  }
}
ll query(ll id, ll i) { // 查询下标为 id 的树状数组的前 i 个元素的和
  ll s = 0;
  while (i > 0) {
    s += tree[id][i];
    i -= lowbit(i);
  }
  return s;
}
// 进一步封装为 add_K 和 get
void add_K(ll l, ll b, ll x) { // 将 l, l+k, l+2k, ... , l+(b-1)k 共 b 个元素都加上 x
  ll id = (l % k ? l % k : k); // 树状数组的下标
  ll s = (l - id) / k + 1;
  add(id, s, x); // 差分
  add(id, s + b, -x);
}
ll get(ll i) { // 查询 i 元素的值
  ll id = (i % k ? i % k : k); // 树状数组的下标
  ll s = (i - id) / k + 1;
  return query(id, s);
}

int main(void) {
  cin >> n >> m >> q >> k;
  for (ll i = 1; i <= n; i++)
    for (ll j = 1; j <= m; j++) cin >> mp[i][j];
  for (ll i = 1; i <= q; i++) cin >> op[i].c >> op[i].a >> op[i].b;

  x = 1, y = 1;

  for (ll i = 1; i <= q; i++) {
    move(change(op[i].c, get(i)), op[i].a);
    if (mp[x][y] == 'X' && op[i].b > 0)
      add_K(i + k, op[i].b, 1);
  }

  cout << x << ' ' << y;

  return 0;
}
2024/9/22 19:27
加载中...