逐月晴月杯
A. 无限旅馆
题目描述
有一个序列
- 令
。 - 令
。 - 求
的1值或确定序列长度小于 。
思路
由于 2 操作至多进行
- 每次不断往前跳,如果是连续的 1 就一起跳过去。
空间复杂度
代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 100001;
struct Node {
int op, x;
}s[MAXN];
int q, len, f[MAXN], fa[18][MAXN], cnt[MAXN], fir[MAXN];
int Get(int i, int p) {
if(!i) {
return 1;
}else if(s[i].op == 2) {
return (p % 2 ? s[i].x : Get(f[i], p / 2));
}else if(p > cnt[i]) {
return Get(fir[i], p - cnt[i]);
}else {
for(int j = 17; j >= 0; --j) {
if(((p - 1) >> j) & 1) {
i = fa[j][i];
}
}
return s[i].x;
}
}
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> q;
len = 1;
for(int i = 1, last = 0; i <= q; ++i) {
cin >> s[i].op >> s[i].x;
f[i] = last;
if(s[i].op == 1) {
len = min(int(1e9) + 1, len + 1);
cnt[i] = 1;
fir[i] = last;
if(s[last].op == 1) {
fa[0][i] = last;
fir[i] = fir[last];
cnt[i] += cnt[last];
for(int j = 1; j <= 17; ++j) {
fa[j][i] = fa[j - 1][fa[j - 1][i]];
}
}
last = i;
}else if(s[i].op == 2) {
len = min(int(1e9) + 1, 2 * len);
last = i;
}else if(s[i].op == 3) {
cout << (s[i].x > len ? -1 : Get(last, s[i].x)) << "\n";
}
}
return 0;
}
D. 镜面迷宫
题目描述
有一个由斜着/横/竖的镜面组成的
思路
可以发现,我们对迷宫建图,一定会组成一个由链/环组成的图。依次处理即可。
时空复杂度均为
代码
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1005, dx[] = {-1, 1, 0, 0}, dy[] = {0, 0, -1, 1};
int n, m, q, nxt[4 * MAXN * MAXN], cnt[4 * MAXN * MAXN], in[4 * MAXN * MAXN], ans[4 * MAXN * MAXN];
bool vis[4 * MAXN * MAXN], flag[4 * MAXN * MAXN];
char c[MAXN][MAXN];
int id(int x, int y, int d) {
return d * n * m + (x - 1) * m + y;
}
bool add(int x, bool f) {
x -= (x > 3 * n * m ? 3 : (x > 2 * n * m ? 2 : (x > n * m ? 1 : 0))) * n * m;
flag[x] = flag[x + n * m] = flag[x + 2 * n * m] = flag[x + 3 * n * m] = f;
return 1;
}
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
cin >> n >> m;
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
cin >> c[i][j];
}
}
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
for(int d : {0, 1, 2, 3}) {
int x = i + dx[d], y = j + dy[d], nd;
if(x >= 1 && x <= n && y >= 1 && y <= m) {
if(c[x][y] == '-') {
nd = (!d ? 1 : (d == 1 ? 0 : d));
}else if(c[x][y] == '|') {
nd = (d == 2 ? 3 : (d == 3 ? 2 : d));
}else if(c[x][y] == '/') {
nd = (!d ? 3 : (d == 1 ? 2 : (d == 2 ? 1 : 0)));
}else if(c[x][y] == '\\') {
nd = (!d ? 2 : (d == 1 ? 3 : (d == 2 ? 0 : 1)));
}
nxt[id(x, y, nd)] = id(i, j, d);
in[id(i, j, d)]++;
cnt[id(x, y, nd)] = (d != nd);
}
}
}
}
for(int i = 1; i <= 4 * n * m; ++i) {
if(!in[i]) {
int u = i, res = 0;
for(; u; ans[u] = res, vis[u] = 1, res += (cnt[u] && !flag[u]), (cnt[u] && add(u, 1)), u = nxt[u]) {
}
u = i;
for(; u; add(u, 0), u = nxt[u]) {
}
}
}
for(int i = 1; i <= 4 * n * m; ++i) {
if(!vis[i]) {
int u = i, res = 0;
for(; !vis[u]; res += (cnt[u] && !flag[u]), (cnt[u] && add(u, 1)), vis[u] = 1, u = nxt[u]) {
}
u = i;
do {
ans[u] = res;
add(u, 0);
u = nxt[u];
}while(u != i);
}
}
cin >> q;
for(int i = 1, x, y, d; i <= q; ++i) {
string s;
cin >> x >> y >> s;
d = (s == "above" ? 0 : (s == "below" ? 1 : (s == "left" ? 2 : 3)));
cout << ans[id(x, y, d)] << "\n";
}
return 0;
}
本文作者:yaosicheng124
本文链接:https://www.cnblogs.com/yaosicheng124/p/18500392
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步