HDU5469 树分治、hash
2015-10-06 18:11
337 查看
题意:问能否在树上找到一条路径使得路径经过的点的单词可以组成提问的串~~
树分治 肯定还有hash~~~
sb的想法就不说了~~~
这里开一个int in_pre[]、in_suf来记录是这个前缀以及这个后缀是否出现了 int型用来当时间戳~~
直接进行点分治、然后对于当前点的子树要进行DFS、4次
第一次找出当前子树(不包括根)、串的后缀,看看之前的子树没有前缀进行匹配
第二次找出当前子树(包括根)、串的前缀,看看之前的子树有没有后缀进行匹配
第三第四次进行更新信息~~
树分治 肯定还有hash~~~
sb的想法就不说了~~~
这里开一个int in_pre[]、in_suf来记录是这个前缀以及这个后缀是否出现了 int型用来当时间戳~~
直接进行点分治、然后对于当前点的子树要进行DFS、4次
第一次找出当前子树(不包括根)、串的后缀,看看之前的子树没有前缀进行匹配
第二次找出当前子树(包括根)、串的前缀,看看之前的子树有没有后缀进行匹配
第三第四次进行更新信息~~
#include <algorithm> #include <iostream> #include<string.h> #include <fstream> #include <math.h> #include <vector> #include <cstdio> #include <string> #include <queue> #include <stack> #include <map> #include <set> #define exp 1e-8 #define fi first #define se second #define ull unsigned long long #define INF 0x3f3f3f3f #define pb(a) push_back(a) #define mp(a,b) make_pair(a,b) #define all(a) a.begin(),a.end() #define mm(a,b) memset(a,b,sizeof(a)); #define for0(a,b) for(int a=0;a<=b;a++)//0---(b-1) #define for1(a,b) for(int a=1;a<=b;a++)//1---(b) #define rep(a,b,c) for(int a=b;a<=c;a++)//b---c #define repp(a,b,c)for(int a=b;a>=c;a--)/// #define cnt_one(i) __builtin_popcount(i) #define stl(c,itr) for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++) using namespace std; void bug(string m="here"){cout<<m<<endl;} template<typename __ll> inline void READ(__ll &m){__ll x=0,f=1;char ch=getchar();while(!(ch>='0'&&ch<='9')){if(ch=='-')f=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}m=x*f;} template<typename __ll>inline void read(__ll &m){READ(m);} template<typename __ll>inline void read(__ll &m,__ll &a){READ(m);READ(a);} template<typename __ll>inline void read(__ll &m,__ll &a,__ll &b){READ(m);READ(a);READ(b);} template<typename __ll>inline void read(__ll &m,__ll &a,__ll &b,__ll &c){READ(m);READ(a);READ(b);READ(c);} template<typename __ll>inline void read(__ll &m,__ll &a,__ll &b,__ll &c,__ll &d){READ(m);READ(a);READ(b);READ(c);read(d);} template < class T > inline void out(T a){if(a>9)out(a/10);putchar(a%10+'0');} template < class T > inline void outln(T a){if(a>9)out(a/10);putchar(a%10+'0');puts("");} template < class T > inline void out(T a,T b){out(a);putchar(' ');out(b);} template < class T > inline void outln(T a,T b){out(a);putchar(' ');outln(b);} template < class T > inline void out(T a,T b,T c){out(a);putchar(' ');out(b);putchar(' ');out(c);} template < class T > inline void outln(T a,T b,T c){out(a);putchar(' ');outln(b);putchar(' ');outln(b);} template < class T > T gcd(T a, T b) { return b ? gcd(b, a % b) : a; } template < class T > T lcm(T a, T b) { return a / gcd(a, b) * b; } template < class T > inline void rmin(T &a, const T &b) { if(a > b) a = b; } template < class T > inline void rmax(T &a, const T &b) { if(a < b) a = b; } template < class T > T pow(T a, T b) { T r = 1; while(b > 0) { if(b & 1) r = r * a; a = a * a; b /= 2; } return r; } template < class T > T pow(T a, T b, T mod) { T r = 1; while(b > 0) { if(b & 1) r = r * a % mod; a = a * a % mod; b /= 2; } return r; } const int mod=0x7FFFFFFF; const int maxn=10010; ull pre[maxn],suf[maxn],f[maxn]; const ull seed=31; int in_pre[maxn],in_suf[maxn],idx; bool flag; const int cnt_edge=maxn*2; //修改啊 const int cnt_v=maxn; int head[cnt_v],cnt_e; struct EDGE{int u,v,next,cost;}edge[cnt_edge]; void init(){cnt_e=0;memset(head,-1,sizeof(head));} void addedge(int u,int v,int cost=0) {edge[cnt_e].u=u;edge[cnt_e].v=v;edge[cnt_e].cost=cost;edge[cnt_e].next=head[u];head[u]=cnt_e++;} int n,k; int root,tot; int minn,size[maxn];///minn:衡量某个节点是否能当重心,minn越小 就越可以当重心、size[i] i子树的大小 bool del[maxn];///记录是否已经删除这个点... char ch[maxn],s[maxn]; void getroot(int u,int fa) { size[u]=1; int maxn=0; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v==fa||del[v])continue;///这里必须要加上del[v] getroot(v,u); size[u]+=size[v]; maxn=max(maxn,size[v]); } maxn=max(maxn,tot-size[u]); if(maxn<minn)root=u,minn=maxn; } void dfs1(int u,int fa,ull len,int deep,int op)///找后缀~~不包含头~~ { len%=mod; if(flag||deep>=k)return; if(suf[deep]==len&&in_pre[k-deep]==idx&&op==0) { flag=1; return; } if(suf[deep]==len&&op==1) in_suf[deep]=idx; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v==fa||del[v])continue; dfs1(v,u,(len+(ch[v]-'a'+1)*f[deep])&mod,deep+1,op); } } void dfs2(int u,int fa,ull len,int deep,int op)///找前缀、包括根~~ { if(flag||deep>k)return; if(pre[deep]==len&&in_suf[k-deep]==idx&&op==0) { flag=1; return; } if(pre[deep]==len&&op==1) in_pre[deep]=idx; for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(v==fa||del[v])continue; dfs2(v,u,(len+(ch[v]-'a'+1)*f[deep])&mod,deep+1,op); } } void word(int u) { del[u]=1; in_suf[0]=in_pre[0]=++idx; if(ch[u]-'a'+1==pre[1])in_pre[1]=idx;///预处理出这个root单独做前缀~~ for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(del[v])continue; dfs1(v,u,ch[v]-'a'+1,1,0);///寻找后缀~~ if(flag){return;} dfs2(v,u,(ch[v]-'a'+1)*31+(ch[u]-'a'+1),2,0);///寻找前缀~~ if(flag){return;} dfs1(v,u,ch[v]-'a'+1,1,1);///寻找后缀~~ dfs2(v,u,(ch[v]-'a'+1)*31+(ch[u]-'a'+1),2,1);///寻找前缀~~ } for(int i=head[u];i!=-1;i=edge[i].next) { int v=edge[i].v; if(del[v])continue; minn=INF,tot=size[v]; getroot(v,u); word(root); } } int main() { f[0]=1; for1(i,10000)f[i]=f[i-1]*seed&mod; int cas; read(cas); for1(tt,cas) { init(); read(n); for1(i,n-1) { int a,b; read(a,b); addedge(a,b); addedge(b,a); } scanf("%s%s",ch+1,s); k=strlen(s);pre[0]=suf[0]=0; for(int i=0;i<k;i++) pre[i+1]=(pre[i]*31+s[i]-'a'+1)&mod; reverse(s,s+k); for(int i=0;i<k;i++) suf[i+1]=(suf[i]*31+s[i]-'a'+1)&mod; printf("Case #%d: ",tt); if(k==1) { for1(i,n)if(ch[i]==s[0])flag=1; if(flag==1) puts("Find"); else puts("Impossible"); continue; } idx=flag=0; memset(in_pre,0,sizeof in_pre); memset(in_suf,0,sizeof in_suf); memset(del,0,sizeof del); minn=INF,tot=n; getroot(1,0); word(root); if(flag==1) puts("Find"); else puts("Impossible"); } }
相关文章推荐
- 黑马程序员——OC语言加强---@property参数
- PostGIS解压版安装
- CSS3学习笔记(2)—左右跳动的红心
- MATLAB - 为什么imshow(g,[])可以正常显示,而imshow(g)却显示空白图像?
- Ubuntu15.04安装Android开发环境
- 黑马程序员——OC语言加强---内存管理的基本概念及范围
- C# SQLite 数据库开发(1)------数据库的下载、配置和操作
- OC中得构造方法
- android UI界面设计(2)
- Python笔记:logging模块使用
- 动画效果实现
- OC字典
- dynamic_cast与typeid关键字
- 主从服务器同步
- foj 犯罪嫌疑人 (脑洞题_)
- 百度2016研发工程师在线编程题
- iOS:多线程同步加锁的简单介绍
- hdu 5428 The Factor 找质因子
- 关于@RequestBody 不能json to pojo
- 堆区、栈区和静态存储区详解