首页 > 代码库 > HDU 4125 Moles 线段树+KMP
HDU 4125 Moles 线段树+KMP
题意:
给定n,
下面是1-n的排列。
下面一个二进制子串。
先按给定的排列建出二叉树。
然后遍历树(根->左子树->根->右子树->根)
遍历这个节点时 若权值为奇数入栈一个1,若为偶数入栈一个0
得到一个母串。
问母串中出现了几次子串。
思路:
先是建树得到母串,然后求子串个数就是裸的KMP。
建树就是找个规律,然后用线段树维护一下输入的排列
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #pragma comment(linker, "/STACK:1024000000,1024000000") typedef long long ll; #define lson l, mid, rt<<1 #define rson mid+1, r, rt<<1|1 template <class T> inline bool rd(T &ret) { char c; int sgn; if(c=getchar(),c==EOF) return 0; while(c!='-'&&(c<'0'||c>'9')) c=getchar(); sgn=(c=='-')?-1:1; ret=(c=='-')?0:(c-'0'); while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0'); ret*=sgn; return 1; } template <class T> inline void pt(T x) { if (x <0) { putchar('-'); x = -x; } if(x>9) pt(x/10); putchar(x%10+'0'); } // const int N = 600000+5; const int M = 70000+5; int mi[N<<2], pos[N]; inline void up(int& fa, int& ls, int& rs) { if (ls>rs) fa = rs; else fa = ls; } void build(int l, int r, int rt) { if (l == r) { mi[rt] = pos[l]; } else { int mid = (l+r)>>1; build(lson); build(rson); up(mi[rt], mi[rt<<1], mi[rt<<1|1]); } } int query(int L, int R, int l, int r, int rt) { if (L<= l && r<=R) { return mi[rt]; } else { int mid = (l+r)>>1; if (L>mid) return query(L, R, rson); else if (R<=mid) return query(L, R, lson); else return min(query(L, mid, lson), query(mid+1, R, rson)); } } void update(int p, int v, int l, int r, int rt) { if (l == r) { mi[rt] = v; } else { int mid = (l+r)>>1; if (p <= mid) update(p, v, lson); else update(p, v, rson); up(mi[rt], mi[rt<<1], mi[rt<<1|1]); } } int T = 0, n, a[N], L[N], R[N]; char s[M], ch[N*3]; int nex[M], top; void dfs(int u, int l, int r) { update(u, n+1, 1, n, 1); int v = query(l, u, 1, n, 1); if (v != n+1) { L[u] = a[v]; dfs(a[v], l, u); } v = query(u, r, 1, n, 1); if (v != n+1) { R[u] = a[v]; dfs(a[v], u, r); } } void f(int u) { char c; if (u&1) c = '1'; else c = '0'; ch[top++] = c; if (L[u] != -1) { f(L[u]); ch[top++] = c; } if (R[u] != -1) { f(R[u]); ch[top++] = c; } } void work() { int v, len, idx, ans = 0; rd(n); for (int i = 1; i <= n; ++i) { rd(a[i]); pos[a[i]] = i; } build(1, n, 1); memset(L, -1, sizeof L); memset(R, -1, sizeof R); dfs(a[1], 1, n); // scanf("%s", s); len = strlen(s); nex[0] = nex[1] = 0; for (int i = 1; i < len; ++i) { int j = nex[i]; while (j && s[j] != s[i]) j = nex[j]; if (s[i] == s[j]) nex[i+1] = j+1; else nex[i+1] = 0; } // top = 0; f(a[1]); idx = 0; for (int i = 0; i < top; ++i) { while (idx && s[idx] != ch[i]) idx = nex[idx]; if (s[idx] == ch[i]) ++ idx; if (idx == len) { ++ ans; idx = nex[idx]; } } printf("Case #%d: %d\n", ++T, ans); } int main() { int cas; scanf("%d", &cas); while (cas-->0) work(); return 0; }
HDU 4125 Moles 线段树+KMP
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。