【洛谷 T47488】 D:希望 (点分治)
题目链接
看到这种找树链的题目肯定是想到点分治的。
我码了一下午,\(debug\)一晚上,终于做到只有两个点TLE了。
我的是不完美做法
加上特判\(A\)了这题qwq
记录每个字母在母串中出现的所有位置,我用的邻接表实现。
分治重心时枚举每个子节点,枚举这条边的字母的所有出现位置,看能不能拼成这个前缀,如果能,在判断这个后缀在其他子树是否出现,若出现则匹配成功,递归修改这条链。
太暴力了。TLE是肯定的
晚上和出题人聊了很久\(qwq\)
#include <cstdio>
#include <algorithm>
#include <cstring>
#define re register
#define il inline
using 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;
}
【洛谷 T47488】 D:希望 (点分治)的更多相关文章
- 洛谷SP22343 NORMA2 - Norma(分治,前缀和)
洛谷题目传送门 这题推式子恶心..... 考虑分治,每次统计跨过\(mid\)的所有区间的答案和.\(i\)从\(mid-1\)到\(l\)枚举,统计以\(i\)为左端点的所有区间. 我们先维护好\( ...
- Poj1741/洛谷P4718 Tree(点分治)
题面 有多组数据:Poj 无多组数据:洛谷 题解 点分治板子题,\(calc\)的时候搞一个\(two\ pointers\)扫一下统计答案就行了. #include <cmath> #i ...
- 洛谷 4721 【模板】分治 FFT——分治FFT / 多项式求逆
题目:https://www.luogu.org/problemnew/show/P4721 分治FFT:https://www.cnblogs.com/bztMinamoto/p/9749557.h ...
- 洛谷P3810 陌上花开(CDQ分治)
洛谷P3810 陌上花开 传送门 题解: CDQ分治模板题. 一维排序,二维归并,三维树状数组. 核心思想是分治,即计算左边区间对右边区间的影响. 代码如下: #include <bits/st ...
- 洛谷P2664 树上游戏(点分治)
题意 题目链接 Sol 神仙题..Orz yyb 考虑点分治,那么每次我们只需要统计以当前点为\(LCA\)的点对之间的贡献以及\(LCA\)到所有点的贡献. 一个很神仙的思路是,对于任意两个点对的路 ...
- 洛谷P4169 天使玩偶 CDQ分治
还是照着CDQ的思路来. 但是有一些改动: 要求4个方向的,但是可爱的CDQ分治只能求在自己一个角落方向上的.怎么办?旋转!做4次就好了. 统计的不是和,而是——max!理由如下: 设当前点是(x,y ...
- 2018.07.20 洛谷P4178 Tree(点分治)
传送门 又一道点分治. 直接维护子树内到根的所有路径长度,然后排序+双指针统计答案. 代码如下: #include<bits/stdc++.h> #define N 40005 using ...
- 洛谷 P4721 【模板】分治 FFT 解题报告
P4721 [模板]分治 FFT 题目背景 也可用多项式求逆解决. 题目描述 给定长度为 \(n−1\) 的数组 \(g[1],g[2],\dots,g[n-1]\),求 \(f[0],f[1],\d ...
- [洛谷P4721]【模板】分治 FFT_求逆
题目大意:给定长度为$n-1$的数组$g_{[1,n)}$,求$f_{[0,n)}$,要求: $$f_i=\sum_{j=1}^if_{i-j}g_j\\f_0=1$$ 题解:分治$FFT$博客,发现 ...
随机推荐
- iOS开发改变字符串中指定字符颜色,大小等等
NSString *strJTGZ = [NSString stringWithFormat:@"交通管制%d处 ",[jtgz intValue]]; NSMutableAttr ...
- Hive整体优化策略
一 整体架构优化 现在hive的整体框架如下,计算引擎不仅仅支持Map/Reduce,并且还支持Tez.Spark等.根据不同的计算引擎又可以使用不同的资源调度和存储系统. 整体架构优化点: 1 根据 ...
- 原生js 自定义confirm
本文参考博客园另一篇文章:https://www.cnblogs.com/hzj680539/p/5374052.html,在此感谢. 在实际开发当中,考虑到原生js组件,包括alert.confir ...
- exception = {"元数据集合中已存在具有标识“xxx”的项。\r\n参数名: item"}
vs提示:exception = {"元数据集合中已存在具有标识"xxx"的项.\r\n参数名: item"} 出现这个错误说明有重复的字段,有可能是继承的类里 ...
- java出现以下警告:WARN No appenders;WARN Please initialize the log4j的处理方法
编译java或引用别的代码时出现以下警告: log4j:WARN No appenders could be found for logger (org.apache.zookeeper.ZooKee ...
- 在Delphi中如何获得SQL中存储过程的返回值?
示例存储过程:create procedure proc_loginusername varchar(20),password varchar(20)asdeclare @result intsele ...
- UIKit中的几个核心对象的介绍:UIApplication,UIWindow,UIViewController,UIView(layer)简单介绍
UIApplication,UIWindow,UIViewController,UIView(layer)简单介绍 一:UIApplication:单例(关于单例后面的文章中会详细介绍,你现在只要知道 ...
- BZOJ 1045 糖果传递(思维)
设第i个人给了第i+1个人mi个糖果(可以为负),因为最后每个人的糖果都会变成sum/n. 可以得到方程组 mi-mi+1=a[i+1]-sum/n.(1<=i<=n). 把方程组化为mn ...
- 《转》玩转图片Base64编码
引言 图片处理在前端工作中可谓占据了很重要的一壁江山.而图片的 base64 编码可能相对一些人而言比较陌生,本文不是从纯技术的角度去讨论图片的 base64 编码.标题略大,不过只是希望通过一些浅显 ...
- 具体数学二项式至生成函数章-----致敬Kunth
关于标题取得这么奇怪.因为在具体数学中.这两章是分开叙述的.并且分别叙述得淋漓尽致! 我只参悟其中关于生成函数的一小部分内容(暂时于我够用了.) 提二项式系数之前不得不提组合数.以往在高中用的是符号C ...