Antonidas

Time Limit: 4000ms
Memory Limit: 65536KB

This problem will be judged on HDU. Original ID: 5469
64-bit integer IO format: %I64d      Java class name: Main

 

Given a tree with N vertices and N−1 edges. Each vertex has a single letter Ci. Given a string S, you are to choose two vertices A and B, and make sure the letters catenated on the shortest path from A to B is exactly S. Now, would you mind telling me whether the path exists?

Input
The first line is an integer T, the number of test cases.
For each case, the first line is an integer N. Following N−1 lines contains two integers a and b, meaning there is an edge connect vertex a and vertex b.
Next line contains a string C, the length of C is exactly N. String C represents the letter on each vertex.
Next line contains a string S.
$1\leq T\leq 200, 1\leq N\leq 10^4, 1\leq a,b\leq N, a\not = b, |C|=N, 1\leq |S|\leq 10^4$. String C and S both only contain lower case letters.

Output
First, please output "Case #k: ", k is the number of test case. See sample output for more detail.
If the path exists, please output “Find”. Otherwise, please output “Impossible”.

Sample Input

2

7
1 2
2 3
2 4
1 5
5 6
6 7
abcdefg
dbaefg 5
1 2
2 3
2 4
4 5
abcxy
yxbac

Sample Output

Case #1: Find
Case #2: Impossible

Source

 
解题:点分治+hash
 debug大半天的成果啊
比如一个目标串是$abcdefg$,假设我们树分治的时候,选的根恰好是$d$,那么我们需要的怎样的hash信息?是不是从$d->a$以及$d->g$的hash信息啊,注意方向。d才是高位!!!
所以我们要预处理出来目标串每个字符么,向左走到端点已经向右走到端点的hash值。
在树分治的时候,我们可以从根到当前点,走出一条路,路上的点就会hash出一个值,根据深度,我们可以看看它跟这个长度的前缀配不配,或者跟这个长度的后缀配不配,配的话,我们要分别找剩下长度的后缀或者前缀是否存在。
比放说根就是$d$,当前走到深度4,那么我们就可以看看目标串从4位置hash到 1位置的hash跟当前路径的hash值等否?如果相等,那么需要一段什么样的值呢?
需要一个后缀,从d开始,走到g这段的hash值,是否在前面的搜索过程中出现过,如果出现过,那么好了a到d的有了,d到g的也有了,那么a到g的就有了,答案就找到了。
 #include <bits/stdc++.h>
using namespace std;
using ULL = unsigned long long;
const int maxn = ;
const ULL Base = ;
struct arc{
int to,next;
arc(int x = ,int y = -){
to = x;
next = y;
}
}e[maxn<<];
bool vis[maxn];
int head[maxn],sz[maxn],maxson[maxn],pre[maxn],suf[maxn],tot,len,cnt;
ULL Pre[maxn],Suf[maxn],B[maxn] = {};
char sa[maxn],sb[maxn];
void add(int u,int v){
e[tot] = arc(v,head[u]);
head[u] = tot++;
}
void dfs(int u,int fa){
sz[u] = ;
maxson[u] = ;
for(int i = head[u]; ~i; i = e[i].next){
if(e[i].to == fa || vis[e[i].to]) continue;
dfs(e[i].to,u);
sz[u] += sz[e[i].to];
maxson[u] = max(maxson[u],sz[e[i].to]);
}
}
int FindRoot(int sum,int u,int fa){
int ret = u;
maxson[u] = max(maxson[u],sum - sz[u]);
for(int i = head[u]; ~i; i = e[i].next){
if(e[i].to == fa || vis[e[i].to]) continue;
int x = FindRoot(sum,e[i].to,u);
if(maxson[x] < maxson[ret]) ret = x;
}
return ret;
}
bool cao(int u,ULL w,int fa,int depth,bool op) {
if(depth > len) return false;
w = w*Base + (ULL)sa[u];
if(op) {
if(w == Pre[depth] && suf[depth] == cnt) return true;
if(w == Suf[len - depth + ] && pre[len - depth + ] == cnt) return true;
} else {
if(w == Pre[depth]) pre[depth] = cnt;
if(w == Suf[len - depth + ]) suf[len - depth + ] = cnt;
}
for(int i = head[u]; ~i; i = e[i].next) {
if(vis[e[i].to] || e[i].to == fa) continue;
if(cao(e[i].to,w,u,depth + ,op)) return true;
}
return false;
}
bool solve(int u){
dfs(u,);
if(sz[u] < len) return false;
int root = FindRoot(sz[u],u,);
vis[root] = true;
++cnt;
ULL w = sa[root];
if(w == Pre[len]) return true;
if(w == Pre[]) pre[] = cnt;
if(w == Suf[len]) suf[len] = cnt;
for(int i = head[root]; ~i; i = e[i].next){
if(vis[e[i].to]) continue;
if(cao(e[i].to,w,root,,true)) return true;
cao(e[i].to,w,root,,false);
}
for(int i = head[root]; ~i; i = e[i].next){
if(vis[e[i].to]) continue;
if(solve(e[i].to)) return true;
}
return false;
}
int main(){
int kase,n,u,v,cs = ;
for(int i = ; i < maxn; ++i) B[i] = B[i-]*Base;
scanf("%d",&kase);
while(kase--){
scanf("%d",&n);
memset(head,-,sizeof head);
memset(vis,false,sizeof vis);
memset(pre,,sizeof pre);
memset(suf,,sizeof suf);
tot = ;
for(int i = ; i < n; ++i){
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
scanf("%s%s",sa + ,sb + );
len = strlen(sb + );
for(int i = ; i <= len; ++i) Pre[i] = Pre[i-] + B[i-]*sb[i];
Suf[len + ] = ;
for(int i = len; i > ; --i) Suf[i] = Suf[i+] + B[len - i]*sb[i];
printf("Case #%d: %s\n",cs++,solve()?"Find":"Impossible");
}
return ;
}

HDU 5469 Antonidas的更多相关文章

  1. hdu 5469 Antonidas(树的分治+字符串hashOR搜索+剪枝)

    题目链接:hdu 5469 Antonidas 题意: 给你一颗树,每个节点有一个字符,现在给你一个字符串S,问你是否能在树上找到两个节点u,v,使得u到v的最短路径构成的字符串恰好为S. 题解: 这 ...

  2. hdu 5469 Antonidas (dfs+剪枝)2015 ACM/ICPC Asia Regional Shanghai Online

    题意: 给出一棵树,再给出每个节点上的值(一个char字符)这些值以一个字符串s1表示,然后给出一个s2字符串,问在这棵树上是否存在两个点,从一个点走到另一个点所经过的路径上的char字符组成的字符串 ...

  3. HDU 5469 Antonidas (树形DP,暴力)

    题意: 给一棵n节点的树图,每个点都是一个小写字母,要求找到两个点(a,b),从a->b的路径上形成了一个字符串为s.给出s,问是否存在这样的点对. 思路: 考虑一个点,要么从该点出发,要么在该 ...

  4. 【HDU5469】Antonidas(点分治,字符串哈希)

    [HDU5469]Antonidas(点分治,字符串哈希) 题面 HDU Vjudge 题解 啊哈?什么垃圾一眼点分治+Hash判断,哈哈哈哈哈,让我来码码码. 诶,怎么WA了.改改改改改. 诶,怎么 ...

  5. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  6. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  7. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  8. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  9. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

随机推荐

  1. fgetcsv()函数

    fgetcsv()函数.fgetcsv()函数可以读取指定文件的当前行,使用CSV格式解析出字段,并返回一个包含这些字段的数组.语法格式如下:array fgetcsv(resource $handl ...

  2. 生产环境中配置的samba

    实验需求: 由于实验室纳新一帮新孩子,搭建samba主要是临时共享一些学习资源的,基本上大家用的都是windows.而且这个服务可以让他们在校园的里的个个角落都可以访问到,所以给挂了学校的公网,不过我 ...

  3. AJPFX总结线程创建的两种方法

    创建线程的第一种方式:继承Thread ,由子类复写run方法.步骤:1,定义类继承Thread类:2,目的是复写run方法,将要让线程运行的代码都存储到run方法中:3,通过创建Thread类的子类 ...

  4. AJPFX总结方法重载与方法重写的区别

    方法重载在同一个类中,可以出现同名方法,但是这些同名方法的参数列表必须不同,这样定义方法叫做方法重载.方法重载的特点重载的注意事项重载与返回值无关重载与具体的变量标识符无关重载只与方法名与参数相关重载 ...

  5. java只http改成https访问

    目录 生成keystore文件 修改tomcat中的server.xml文件 配置浏览器 生成keystore文件: 1.在tomcat的bin 目录下输入命令:keytool -genkeypair ...

  6. 【转】一篇文章,教你学会Git

    一篇文章,教你学会Git 在日常工作中,经常会用到Git操作.但是对于新人来讲,刚上来对Git很陌生,操作起来也很懵逼.本篇文章主要针对刚开始接触Git的新人,理解Git的基本原理,掌握常用的一些命令 ...

  7. iOS逆向实战与工具使用(微信添加好友自动确认)

    iOS逆向实战与工具使用(微信添加好友自动确认) 原文链接 源码地址 WeChatPlugin-iOS Mac OS 版微信小助手(远程控制.消息防撤回.自动回复.微信多开) 一.前言 本篇主要实现在 ...

  8. vue+element ui项目总结点(一)select、Cascader级联选择器、encodeURI、decodeURI转码解码、mockjs用法、路由懒加载三种方式

    不多说上代码: <template> <div class="hello"> <h1>{{ msg }}</h1> <p> ...

  9. iOS猜拳游戏源码

    利用核心动画和Quartz2D做的一个小游戏.逻辑十分简单. 源码下载:http://code.662p.com/<ignore_js_op> 详细说明:http://ios.662p.c ...

  10. Python 语言规范

    Python 语言规范 pychecker  对你的代码运行pychecker 定义: pychecker 是一个在Python 源代码中查找bug 的工具. 对于C 和C++这样的不那 么动态的( ...