HDU5469 Antonidas(树分治&&哈希)
给你一颗点上有字符的树,问一个给定的字符串是否是这棵树上的两点的路径。
树分治的思想就是每次找重心,重心下的子问题分解去做,然后就是合并了。合并的时候用一个总的set<pair<len,hash>> 去存从根节点往下走的长度以及对应的hash值,判的时候只需要看下是否已经存在 m-len,以及对应的前缀(或者后缀)的哈希值,然后再加进来。
两个优化的点是,1是递归解子问题的时候如果子树规模小于要给的字符串可以不用递归下去。2是存pair的时候只需要存前缀的pair以及后缀的pair,其它的都不用存。
加了这些优化之后我的程度勉强能在4000ms内通过。看来我树分治的写法还是太慢了。。
#pragma warning(disable:4996)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <ctime>
#include <map>
#include <set>
using namespace std; #define maxn 10010
#define ll long long
#define MP make_pair vector<int> G[maxn];
bool centroid[maxn];
int ssize[maxn];
char val[maxn];
char tar[maxn];
set<pair<ll, ll> > sta;
set<pair<ll, ll> >::iterator it;
int n, m; ll mod_num;
ll mod;
ll xpow[maxn];
ll pre[maxn];
ll post[maxn]; ll xorr(ll x, ll y)
{
return (x*mod_num%mod + y) % mod;
} int compute_ssize(int v, int p)
{
int c = 1;
for (int i = 0; i<G[v].size(); ++i){
int w = G[v][i];
if (w == p || centroid[w]) continue;
c += compute_ssize(G[v][i], v);
}
ssize[v] = c;
return c;
} pair<int, int> search_centroid(int v, int p, int t)
{
pair<int, int> res = make_pair(INT_MAX, -1);
int s = 1, m = 0;
for (int i = 0; i < G[v].size(); ++i){
int w = G[v][i];
if (w == p || centroid[w]) continue;
res = min(res, search_centroid(w, v, t));
m = max(m, ssize[w]);
s += ssize[w];
}
m = max(m, t - s);
res = min(res, make_pair(m, v));
return res;
} void enumerate_mul(int v, int p, pair<ll, ll> d, set<pair<ll, ll> > &ds)
{
if (!ds.count(d)) ds.insert(d);
for (int i = 0; i < G[v].size(); ++i){
int w = G[v][i];
if (w == p || centroid[w]) continue;
enumerate_mul(w, v, MP(d.first + 1, xorr(d.second, val[w])), ds);
}
} bool judge(pair<ll, ll> x, const set<pair<ll, ll> >& tds)
{
if (pre[x.first] == x.second){
return tds.count(MP(m - x.first, post[x.first + 1]));
}
if (post[m - x.first + 1] == x.second){
return tds.count(MP(m - x.first, pre[m - x.first]));
}
return false;
} bool solve(int v)
{
compute_ssize(v, -1);
int s = search_centroid(v, -1, ssize[v]).second;
centroid[s] = true;
for (int i = 0; i<G[s].size(); ++i){
if (centroid[G[s][i]]) continue;
if (ssize[G[s][i]] < m){
continue;
}
if (solve(G[s][i])) {
return true;
}
}
sta.clear();
sta.insert(MP(1, val[s]));
if (m == 1 && val[s] == tar[1]){
return true;
}
set<pair<ll, ll> > tds;
for (int i = 0; i<G[s].size(); ++i){
if (centroid[G[s][i]]) continue;
tds.clear();
enumerate_mul(G[s][i], s, MP(1, val[G[s][i]]), tds);
it = tds.begin();
while (it != tds.end()){
if (judge(*it, sta)){
return true;
}
++it;
}
it = tds.begin();
while (it != tds.end()){
ll one = (*it).first;
ll two = (*it).second;
pair<ll, ll> vv;
if (one > m){
++it; continue;
}
if (pre[one] != two && post[m - one + 1] != two){
++it;
continue;
}
if (tar[one + 1] != val[s] && tar[m - one] != val[s]){
++it;
continue;
}
vv.first = one + 1;
vv.second = (xpow[one] * val[s] % mod + two) % mod;
if (!sta.count(vv)){
sta.insert(vv);
}
++it;
}
}
centroid[s] = false;
return false;
} ll haha[3] = { 37, 23, 53 };
ll tata[2] = { 1000000007, 1000010009 }; int main()
{
int T; cin >> T; int ca = 0;
while (T--)
{
cin >> n;
for (int i = 0; i <= n; ++i) G[i].clear();
int ui, vi;
for (int i = 0; i < n - 1; ++i){
scanf("%d%d", &ui, &vi);
G[ui].push_back(vi);
G[vi].push_back(ui);
}
memset(centroid, 0, sizeof(centroid));
scanf("%s", val + 1);
scanf("%s", tar + 1);
mod_num = haha[rand() % 3];
mod = tata[rand() % 2];
xpow[0] = 1;
for (int i = 1; i <= n; ++i){
xpow[i] = xpow[i - 1] * mod_num%mod;
}
pre[0] = 0;
m = strlen(tar + 1);
for (int i = 1; i <= m; ++i){
pre[i] = (xpow[i - 1] * tar[i] % mod + pre[i - 1]) % mod;
}
post[m + 1] = 0;
for (int i = m; i >= 1; --i){
post[i] = (tar[i] * xpow[m - i] % mod + post[i + 1]) % mod;
}
bool flag = solve(1);
if (flag){
printf("Case #%d: Find\n", ++ca);
}
else{
printf("Case #%d: Impossible\n", ++ca);
}
}
return 0;
}
HDU5469 Antonidas(树分治&&哈希)的更多相关文章
- hdu4812 逆元+树分治
逆元链接:https://www.cnblogs.com/zzqc/p/7192436.html 经典的树分治题 #pragma comment("linker,"/STACK:1 ...
- hdu-5977 Garden of Eden(树分治)
题目链接: Garden of Eden Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/ ...
- 【BZOJ-1468】Tree 树分治
1468: Tree Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 1025 Solved: 534[Submit][Status][Discuss] ...
- HDU 4812 D Tree 树分治+逆元处理
D Tree Problem Description There is a skyscraping tree standing on the playground of Nanjing Unive ...
- BZOJ 2152: 聪聪可可 树分治
2152: 聪聪可可 Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一 ...
- POJ 1741 Tree 树分治
Tree Description Give a tree with n vertices,each edge has a length(positive integer less than 1 ...
- UVALive 7148 LRIP【树分治+线段树】
题意就是要求一棵树上的最长不下降序列,同时不下降序列的最小值与最大值不超过D. 做法是树分治+线段树,假设树根是x,y是其当前需要处理的子树,对于子树y,需要处理出两个数组MN,MX,MN[i]表示以 ...
- BZOJ 2566 xmastree(树分治+multiset)
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=2566 题意:一棵有边权的树.结点有颜色.每次修改一个点的颜色.求每次修改后所有同色 ...
- 树分治&树链剖分相关题目讨论
预备知识 树分治,树链剖分 poj1741 •一棵有n个节点的树,节点之间的边有长度.方方方想知道,有多少个点对距离不超过m 题解 点分治模板题.详见我早上写的http://www.cnblogs ...
随机推荐
- 17 rest-framework框架的基本组件
序列化 创建一个序列化类 简单使用 开发我们的Web API的第一件事是为我们的Web API提供一种将代码片段实例序列化和反序列化为诸如json之类的表示形式的方式.我们可以通过声明与Django ...
- WPF的线程模型
原文:WPF的线程模型 WPF的线程模型 周银辉 谈到多线程,很多人对其可能都不太有好感,觉得麻烦与易出错.所以我们不排除有这样的情况:假设我对“多线程”.“异步”这些字眼潜意识 ...
- 关于 JS 模块化的最佳实践总结
模块化开发是 JS 项目开发中的必备技能,它如同面向对象.设计模式一样,可以兼顾提升软件项目的可维护性和开发效率. 模块之间通常以全局对象维系通讯.在小游戏中,GameGlobal 是全局对象.在小程 ...
- CSS 一些基础知识(优先级、行内元素的一些属性、font-size单位) 怎样不加载图片
CSS大小写不敏感 选择器优先级如下所示: 在属性后面使用 !important 会覆盖页面内任何位置定义的元素样式. 作为style属性写在元素内的样式 id选择器 类选择器 标签选择器 通配符选择 ...
- 《1024伐木累》-小白篇之丽jie(结束篇)-总章节六
往期回顾: 机缘巧合,月侠发现了老王和他心仪女孩儿的秘密,这让他倍感愤怒,一年以后,丽姐又在去往老王家的路上,这让月侠感到历史即将重新上演,他想拦住丽姐,可恰巧丽姐手机没电,失去了联系. 小序 有人 ...
- python学习笔记六:内置函数
一.数学相关 1.绝对值:abs(-1) 2.最大最小值:max([1,2,3]).min([1,2,3]) 3.序列长度:len('abc').len([1,2,3]).len((1,2,3)) 4 ...
- 浅谈传输层协议TCP和UDP
在当今因特网的层次结构中,传输层的协议主要有两种,其一为Transmission Control Protocol,即TCP:其二为User Datagram Protocol,即UDP. 1.TCP ...
- Leetcode 659.分割数组为连续子序列
分割数组为连续子序列 输入一个按升序排序的整数数组(可能包含重复数字),你需要将它们分割成几个子序列,其中每个子序列至少包含三个连续整数.返回你是否能做出这样的分割? 示例 1: 输入: [1,2,3 ...
- 《大道至简》第一章 编程的精义 java伪代码形式
愚公.这位名家身上,浓缩了项目组织者.团队经理.编程人员.技术分析师等众多角色的优秀素质. 愚公移山事件分析: 原始需求:惩山北之塞,出入之迂 项目沟通方式:聚室而某曰 项目目标:毕力平险,指通豫南, ...
- mysql常见面试题目
1, mysql的复制原理以及流程. (1)先问基本原理流程,3个线程以及之间的关联. (2)再问一致性,延时性,数据恢复. (3)再问各种工作遇到的复制bug的解决方法 2,mysql中myisam ...