目录
一、题目
1、题目描述
2、输入输出
2.1输入
2.2输出
3、原题链接
二、解题报告
1、思路分析
不管怎么反转:
起点终点不变
[0, l - 1] 的路径上的点不变
[r, n] 的路径上的点不变
记 op[l - 1]后,坐标为(lx, ly),op[r] 后 为(rx, ry),询问(x, y),[l, r] 的 x偏移量为dx,[l, r]的y偏移量为dy
反转前,我们从(lx, ly) 走 (dx, dy) 走到 (rx, ry)
反转后,相当于从(lx, ly) 走 (dx1, dy1) 到(x, y),再从(x, y) 走 (dx2, dy2) 到 (rx, ry)
其中 dx1 + dx2 = dx, dy1 + dy2 = dy
显然dx1 = rx - x, dy1 = ry - y
即到达(x, y)时候的操作下标为k,那么(dx1, dy1)就是[l, k] 操作的偏移量
我们只需判断 (x, y) 是否在[0, l - 1] || [r, n]出现,以及[lx + dx1, ly + dy1] 是否在[l, r - 1]出现
2、复杂度
时间复杂度: O(NlogN + q logq)空间复杂度:O(N)
3、代码详解
#include <bits/stdc++.h>
using i64 = long long;
using i32 = unsigned int;
using u64 = unsigned long long;
using i128 = __int128;
constexpr int inf32 = 1E9 + 7;
constexpr i64 inf64 = 1E18 + 7;
constexpr int P = 998'244'353;
void solve() {
int n, q;
std::cin >> n >> q;
std::string s;
std::cin >> s;
std::map<std::pair<int, int>, std::vector<int>> mp;
std::vector<std::pair<int, int>> pos(n + 1);
mp[std::pair(0, 0)].push_back(0);
for (int i = 0; i < n; ++ i) {
pos[i + 1].first = pos[i].first + (s[i] == 'R') - (s[i] == 'L');
pos[i + 1].second = pos[i].second + (s[i] == 'U') - (s[i] == 'D');
mp[pos[i + 1]].push_back(i + 1);
}
auto check = [&](const std::pair<int, int> &p, int l, int r) -> bool {
if (!mp.contains(p)) return false;
auto it = std::lower_bound(mp[p].begin(), mp[p].end(), l);
return it != mp[p].end() && *it <= r;
};
for (int i = 0, x, y, l, r; i < q; ++ i) {
std::cin >> x >> y >> l >> r;
int nx = pos[l - 1].first + pos[r].first - x, ny = pos[l - 1].second + pos[r].second - y;
bool f = check(std::pair(x, y), 0, l - 1) ||
check(std::pair(nx, ny), l, r - 1) ||
check(std::pair(x, y), r, n);
f ? std::cout << "YES\n" : std::cout << "NO\n";
}
}
auto FIO = []{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
return 0;
}();
int main () {
#ifdef DEBUG
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int T = 1;
// std::cin >> T;
while (T --)
solve();
return 0;
}