zoukankan      html  css  js  c++  java
  • HDU 5469 Antonidas

    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.
    $1leq Tleq 200, 1leq Nleq 10^4, 1leq a,bleq N, a ot = b, |C|=N, 1leq |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的就有了,答案就找到了。
      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 using ULL = unsigned long long;
      4 const int maxn = 10010;
      5 const ULL Base = 31;
      6 struct arc{
      7     int to,next;
      8     arc(int x = 0,int y = -1){
      9         to = x;
     10         next = y;
     11     }
     12 }e[maxn<<1];
     13 bool vis[maxn];
     14 int head[maxn],sz[maxn],maxson[maxn],pre[maxn],suf[maxn],tot,len,cnt;
     15 ULL Pre[maxn],Suf[maxn],B[maxn] = {1};
     16 char sa[maxn],sb[maxn];
     17 void add(int u,int v){
     18     e[tot] = arc(v,head[u]);
     19     head[u] = tot++;
     20 }
     21 void dfs(int u,int fa){
     22     sz[u] = 1;
     23     maxson[u] = 0;
     24     for(int i = head[u]; ~i; i = e[i].next){
     25         if(e[i].to == fa || vis[e[i].to]) continue;
     26         dfs(e[i].to,u);
     27         sz[u] += sz[e[i].to];
     28         maxson[u] = max(maxson[u],sz[e[i].to]);
     29     }
     30 }
     31 int FindRoot(int sum,int u,int fa){
     32     int ret = u;
     33     maxson[u] = max(maxson[u],sum - sz[u]);
     34     for(int i = head[u]; ~i; i = e[i].next){
     35         if(e[i].to == fa || vis[e[i].to]) continue;
     36         int x = FindRoot(sum,e[i].to,u);
     37         if(maxson[x] < maxson[ret]) ret = x;
     38     }
     39     return ret;
     40 }
     41 bool cao(int u,ULL w,int fa,int depth,bool op) {
     42     if(depth > len) return false;
     43     w = w*Base + (ULL)sa[u];
     44     if(op) {
     45         if(w == Pre[depth] && suf[depth] == cnt) return true;
     46         if(w == Suf[len - depth + 1] && pre[len - depth + 1] == cnt) return true;
     47     } else {
     48         if(w == Pre[depth]) pre[depth] = cnt;
     49         if(w == Suf[len - depth + 1]) suf[len - depth + 1] = cnt;
     50     }
     51     for(int i = head[u]; ~i; i = e[i].next) {
     52         if(vis[e[i].to] || e[i].to == fa) continue;
     53         if(cao(e[i].to,w,u,depth + 1,op)) return true;
     54     }
     55     return false;
     56 }
     57 bool solve(int u){
     58     dfs(u,0);
     59     if(sz[u] < len) return false;
     60     int root = FindRoot(sz[u],u,0);
     61     vis[root] = true;
     62     ++cnt;
     63     ULL w = sa[root];
     64     if(w == Pre[len]) return true;
     65     if(w == Pre[1]) pre[1] = cnt;
     66     if(w == Suf[len]) suf[len] = cnt;
     67     for(int i = head[root]; ~i; i = e[i].next){
     68         if(vis[e[i].to]) continue;
     69         if(cao(e[i].to,w,root,2,true)) return true;
     70         cao(e[i].to,w,root,2,false);
     71     }
     72     for(int i = head[root]; ~i; i = e[i].next){
     73         if(vis[e[i].to]) continue;
     74         if(solve(e[i].to)) return  true;
     75     }
     76     return false;
     77 }
     78 int main(){
     79     int kase,n,u,v,cs = 1;
     80     for(int i = 1; i < maxn; ++i) B[i] = B[i-1]*Base;
     81     scanf("%d",&kase);
     82     while(kase--){
     83         scanf("%d",&n);
     84         memset(head,-1,sizeof head);
     85         memset(vis,false,sizeof vis);
     86         memset(pre,0,sizeof pre);
     87         memset(suf,0,sizeof suf);
     88         tot = 0;
     89         for(int i = 1; i < n; ++i){
     90             scanf("%d%d",&u,&v);
     91             add(u,v);
     92             add(v,u);
     93         }
     94         scanf("%s%s",sa + 1,sb + 1);
     95         len = strlen(sb + 1);
     96         for(int i = 1; i <= len; ++i) Pre[i] = Pre[i-1] + B[i-1]*sb[i];
     97         Suf[len + 1] = 0;
     98         for(int i = len; i > 0; --i) Suf[i] = Suf[i+1] + B[len - i]*sb[i];
     99         printf("Case #%d: %s
    ",cs++,solve(1)?"Find":"Impossible");
    100     }
    101     return 0;
    102 }
    View Code
  • 相关阅读:
    USACO第三道题
    uva350 PseudoRandom Numbers
    uva10879 Code Refactoring
    Scrum 冲刺第一篇 晨曦
    WC.exe 晨曦
    [LeetCode 126] 单词梯II(Word Ladder II)
    [LeetCode 129] 根节点到叶子节点数字求和(Sum Root to Leaf Numbers)
    [LeetCode 125] 验证回文(Valid Palindrome)
    [LeetCode 123] 买入与卖出股票的最佳时机III(Best Time to Buy and Sell Stock III)
    [LeetCode 124] 二叉树最大路径和(Binary Tree Maximum Path Sum)
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4908870.html
Copyright © 2011-2022 走看看