1 条题解
-
1
题意:
只编号的鼹鼠打洞,第只编号为,编号不重复。打的洞的样子符合以为值,以下标为插入顺序的二叉搜索树。现在从根出发,存在左子树则先走左子树,否则往右走,每经过一个洞(结点),如果这个洞的值是奇数,就记录,否则记录,得到的序列是串。注意是序列不是中序遍历得到的序列,每个点最多被经过次:。给定一个串,问在中出现多少次。求出之后就好惹。
关键:
某个点的父亲是 左边的数中 比它小的数中最大的值 或者 比它大的数的最小值。 和都不存在,是根 仅不存在,是的左儿子 仅不存在,是的右儿子 都存在则的右儿子和的左儿子必有一个为空,就放在空的那个地方。 可以用求,,但是我写会;
线段树求,+读入挂 ,不加会 笛卡尔树
笛卡尔树看结点的满足二叉搜索树,看结点的满足堆(按具体实现分为小顶堆or大顶堆,此题小顶堆) 为,为,则满足早点到的一定最浅,满足二叉搜索树。
,匹配用;注意这个二叉搜索树可能是一条链,序列递归求可能会爆栈,用栈模拟即可√。标程
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <map> // 定义常量 const int N = 6e5 + 5; // 全局变量声明 int t, n, x; int fa[N], ls[N], rs[N]; int stk[N], top, stop; char S[N * 5], T[7005]; // dfs 函数实现 void dfs(int u) { stk[top++] = u; while (top) { int u = stk[top - 1]; S[stop++] = (u & 1)? '1' : '0'; if (ls[u]) { stk[top++] = ls[u]; ls[u] = 0; } else if (rs[u]) { stk[top++] = rs[u]; rs[u] = 0; } else { top--; } } S[stop] = '\0'; } // 声明数组 int nt[7000 + 5]; char b[10001]; // kmp_next 函数实现 void kmp_next() { nt[0] = 0; for (int i = 1, j = 0, m = std::strlen(T); i < m; i++) { while (j && T[i]!= T[j]) j = nt[j - 1]; if (T[i] == T[j]) j++; nt[i] = j; } } // kmp 函数实现 int kmp() { kmp_next(); int ans = 0, sn = std::strlen(S), tn = std::strlen(T); for (int i = 0, j = 0; i < sn; i++) { while (j && S[i]!= T[j]) j = nt[j - 1]; if (S[i] == T[j]) j++; if (j == tn) ans++; } return ans; } // 定义结构体 struct node { int id, v; bool operator<(const node &b) const { return v < b.v; } }; // 全局变量声明 int root; node e[N]; // main 函数实现 int main() { scanf("%d", &t); int kase = 0; while (t--) { stop = top = 0; scanf("%d", &n); for (int i = 1; i <= n; i++) scanf("%d", &e[i].v), e[i].id = i; memset(ls, 0, sizeof(ls)); memset(rs, 0, sizeof(rs)); memset(fa, 0, sizeof(fa)); std::sort(e + 1, e + n + 1); stk[0] = 0; for (int i = 1; i <= n; i++) { while (top && e[stk[top]].id > e[i].id) ls[i] = stk[top], top--; fa[i] = stk[top]; fa[ls[i]] = i; if (fa[i]) { rs[fa[i]] = i; } else { root = i; } stk[++top] = i; } scanf("%s", T); stop = top = 0; dfs(root); // printf("%s\n",S); int ans = kmp(); printf("Case #%d: %d\n", ++kase, ans); root = 0; } return 0; }
- 1
信息
- ID
- 2986
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者