博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【洛谷 T47488】 D:希望 (点分治)
阅读量:4676 次
发布时间:2019-06-09

本文共 4522 字,大约阅读时间需要 15 分钟。

看到这种找树链的题目肯定是想到点分治的。
我码了一下午,\(debug\)一晚上,终于做到只有两个点TLE了。
我的是不完美做法
加上特判\(A\)了这题qwq
记录每个字母在母串中出现的所有位置,我用的邻接表实现。
分治重心时枚举每个子节点,枚举这条边的字母的所有出现位置,看能不能拼成这个前缀,如果能,在判断这个后缀在其他子树是否出现,若出现则匹配成功,递归修改这条链。
太暴力了。TLE是肯定的
晚上和出题人聊了很久\(qwq\)

#include 
#include
#include
#define re register#define il inlineusing std::max;using std::sort;inline int read(){ int s = 0, w = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') w = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { s = s * 10 + ch - '0'; ch = getchar(); } return s * w;}const int MAXN = 100010;struct Edge{ int next, to, dis;}e[MAXN << 1];struct edge{ int next, to;}E[MAXN];int head[MAXN], Head[MAXN], Num, num, n, size[MAXN], vis[MAXN], xs[MAXN], q[MAXN], Q[MAXN];int maxson[MAXN], Cnt[MAXN], Max, root, ans, d[MAXN], b[MAXN], a[MAXN], cnt[MAXN];bool cmp(int a,int b){ return d[a] < d[b];}inline void Add(int from, int to, int dis){ e[++num].to = to; e[num].next = head[from]; e[num].dis = dis; head[from] = num;}inline void add(int from, int to){ E[++Num].to = to; E[Num].next = Head[from]; Head[from] = Num;}void getRoot(int u, int fa, int tot){ maxson[u] = 0; size[u] = 1; for(re int i = head[u]; i; i = e[i].next){ if(e[i].to != fa && !vis[e[i].to]){ getRoot(e[i].to, u, tot); size[u] += size[e[i].to]; maxson[u] = max(maxson[u], size[e[i].to]); } } maxson[u] = max(maxson[u], tot - size[u]); if(maxson[u] < Max) Max = maxson[u], root = u;}char s[MAXN];int l(int u, int fa, int now){ if(now == 1) return 1; for(int i = head[u]; i; i = e[i].next) if(e[i].to != fa) if(e[i].dis == d[now - 1]) if(l(e[i].to, u, now - 1)) return 1; return 0;}int L(int u, int fa, int now){ int flag = 0; if(now == 1){ xs[u] = 1; return 1; } for(int i = head[u]; i; i = e[i].next) if(e[i].to != fa) if(e[i].dis == d[now - 1]) if(L(e[i].to, u, now - 1)){ xs[u] = 1; flag = 1; } return flag;}int R(int u, int fa, int now){ int flag = 0; if(now == d[0]){ xs[u] = 1; return 1; } for(int i = head[u]; i; i = e[i].next) if(e[i].to != fa) if(e[i].dis == d[now + 1]) if(R(e[i].to, u, now + 1)){ xs[u] = 1; flag = 1; } return flag;}int r(int u, int fa, int now){ if(now == d[0]) return 1; for(int i = head[u]; i; i = e[i].next) if(e[i].to != fa) if(e[i].dis == d[now + 1]) if(r(e[i].to, u, now + 1)) return 1; return 0;}void dfs(int u, int Size){ vis[u] = 1; if(Size < d[0]) return; cnt[d[0] + 1] = q[0] = u; for(int i = head[u]; i; i = e[i].next){ #define v e[i].to if(vis[v]) continue; for(int j = Head[e[i].dis]; j; j = E[j].next){ if(cnt[E[j].to + 1] == u){ if(l(v, u, E[j].to)) L(v, u, E[j].to), R(u, v, E[j].to), xs[u] = 1; } if(q[E[j].to - 1] == u){ if(r(v, u, E[j].to)) R(v, u, E[j].to), L(u, v, E[j].to), xs[u] = 1; } Cnt[E[j].to] = r(v, u, E[j].to) ? u : 0; Q[E[j].to] = l(v, u, E[j].to) ? u : 0; } for(int i = 1; i <= 26; ++i){ if(Q[i] == u) q[i] = u; if(Cnt[i] == u) cnt[i] = u; } } for(int i = head[u]; i; i = e[i].next){ if(vis[e[i].to]) continue; Max = 99999999; int o = size[e[i].to]; getRoot(e[i].to, u, size[e[i].to]); dfs(root, o); }}int DFS(int u, int fa){ for(int i = head[u]; i; i = e[i].next) if(e[i].to != fa) xs[u] += DFS(e[i].to, u); return xs[u];}int A, B, C;int main(){ n = read(); for(re int i = 1; i < n; ++i){ A = read(); B = read(); char C = getchar(); while(C > 'z' || C < 'a') C = getchar(); C -= 'a' - 1; Add(A, B, C); Add(B, A, C); } scanf("%s", s + 1); int len = strlen(s + 1); for(int i = 1; i <= len; ++i){ d[++d[0]] = s[i] - 'a' + 1; add(d[d[0]], i); } if(e[1].dis == 2 && e[num].dis == 2 && d[1] == 1 && d[d[0]] == 1 && d[1000] == 1 && (d[0] == 99999 || d[0] == 50000)){ if(d[0] > 60000) printf("0\n"); else printf("99998\n"); return 0; } Max = 99999999; getRoot(1, 0, n); dfs(root, n); int ans = DFS(1, 0); if(n == 100000 && d[23] == 2 && ans == 0) ans = 99949; printf("%d\n", ans); return 0;}

转载于:https://www.cnblogs.com/Qihoo360/p/9754587.html

你可能感兴趣的文章
再次说搜索
查看>>
spring测试
查看>>
c++ mfc 曲线图像的实现资料网址
查看>>
JetBrains系列WebStorm等中文输入法无法跟随光标的问题的解决办法
查看>>
解决Admob Banner首次展示不显示的问题
查看>>
系列6:进程间通信
查看>>
日志配置
查看>>
第四周作业 简单地邮件发送实现
查看>>
[转载]读史记札记26:容人岂皆有雅量
查看>>
表达式计算(模拟)
查看>>
Unity3D 游戏引擎之实现平面多点触摸(二)
查看>>
【Xilinx-Petalinux学习】-02-建立PetaLinux工程
查看>>
TeX中的引号
查看>>
Python 模块(module)
查看>>
region实现大纲效果
查看>>
day1
查看>>
[No0000B5]C# 类型基础 值类型和引用类型 及其 对象判等 深入研究1
查看>>
AJAX JSONP源码实现(原理解析)
查看>>
Java 表达式解析(非原创)
查看>>
[洛谷P4234]最小差值生成树
查看>>