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 ...
随机推荐
- java练习——接口与继承
父类与子类的构造方法: 如果父类中有一个默认无参的构造方法,那么子类的构造方法中会自动进行调用.如果父类有自己的构造方法,且这时父类没有默认无参的构造方法,那么在子类的构造方法中,必须要调用父类的某个 ...
- 容器技术Docker
什么是decker容器 简单理解就是将代码和部署环境一起打包的一个容器
- build dynamic libraries for iOS and load them at runtime
编译了libmt.dylib, 和 test 程序调用,均正常.在xcode中显示调用正常,隐式调用则出现问题. 提示 dyld: Library not loaded. 即使存在在/usr/lib/ ...
- laravel5.5开发composer扩展包
目录 1. 下载laravel框架,并命名(framework) 2. 创建相关目录 3. 项目根目录下的composer.json文件中声明命名空间 4. 在包的根目录(packages/arche ...
- lnmp一键安装环境中nginx开启pathinfo
问题及原理可参考:http://www.laruence.com/2009/11/13/1138.html 如果是用lnmp脚本一键安装的开发环境,可以通过如下方式开户pathinfo: 1.注释ng ...
- 洛谷P1331海战
题目描述 在峰会期间,武装部队得处于高度戒备.警察将监视每一条大街,军队将保卫建筑物,领空将布满了F-2003飞机.此外,巡洋船只和舰队将被派去保护海岸线. 不幸的是因为种种原因,国防海军部仅有很少的 ...
- Redis Sorted Set
Redis Sorted Set Redis 有序集合和集合一样也是string类型元素的集合,且不允许重复的成员. 不同的是每个元素都会关联一个double类型的分数.redis正是通过分数来为集合 ...
- CodeForces 549H | 二分答案
参考了这个博客哇 #include<cstdio> #include<algorithm> #include<cstring> #define Max(a,b,c, ...
- 《c程序设计语言》读书笔记-4.14-定义宏交换两个参数
#include <stdio.h> #include <math.h> #include <stdlib.h> #include <string.h> ...
- Codeforces Round #325 (Div. 2) A
A. Alena's Schedule time limit per test 1 second memory limit per test 256 megabytes input standard ...