• HDU5469 Antonidas


    题目

    分析

    拼接字符串,显然是字符串哈希来维护这个信息。

    于是把所有的前缀哈希串预处理一下,再预处理每一个前缀对应的后缀哈希串,然后就可以直接询问当前的串作为后缀是否可以有一个前缀,以及当前作为前缀是否存在后缀。

    然后就做完了。

    代码

    口胡的,题解代码:

    #include<bits/stdc++.h>
    #define MAXN 10010
    #define P 131
    #define ull unsigned long long
    using namespace std;
    const int INF = 0x3f3f3f3f;
    char val[MAXN],s[MAXN];//val为节点字母串,s为待匹配串
    int len;//len为待匹配串的长度
    int n;
    ull pw[MAXN],pre[MAXN],sub[MAXN];//记录幂值,s前缀hash值,s后缀hash值
    int tot,head[MAXN];
    struct edge
    {
        int v,nxt;
    }edg[MAXN << 1];
    inline void addedg(int u,int v)
    {
        edg[tot].v = v;
        edg[tot].nxt = head[u];
        head[u] = tot++;
    }
    int root,ms,sz[MAXN],Size;
    bool vis[MAXN];
    void getroot(int u,int f)//获得重心
    {
        sz[u] = 1;
        int v,mson = 0;
        for(int i = head[u];i != -1;i = edg[i].nxt)
        {
            v = edg[i].v;
            if(vis[v] || v == f) continue;//剔除已经被分治过的点
            getroot(v,u);
            sz[u] += sz[v];
            if(sz[v] > mson) mson = sz[v];
        }
        if(Size - sz[u] > mson) mson = Size-sz[u];//把u看作根节点时u的父亲那一部分也算作子树
        if(ms > mson) ms = mson,root = u;//更新重心
    }
    struct node
    {
        ull hs;//dis链为从节点往重心的hash值
        int dep;//dep为深度
    }dis[MAXN];
    int cnt;
    bool ans;//记录答案
    bool vispre[MAXN],vissub[MAXN];//记录s某个长度的前缀和后缀是否可以得到
    int idpre[MAXN],idsub[MAXN],cpre,csub;//记录哪些长度被标记了,方便重置vispre,vissub
    inline void getdis(int u,int f,ull d,int dep)
    {
        ull w = d+(val[u]-'a'+1)*pw[dep];
        dis[++cnt] = node{w,dep+1};
        int v;
        for(int i = head[u];i != -1;i = edg[i].nxt)
        {
            v = edg[i].v;
            if(v == f || vis[v])
                continue;
            getdis(v,u,w,dep+1);
        }
    }
    inline void solve(int u,int ssize)
    {
        vis[u] = 1;
        cpre = csub = 0;
        if(val[u]-'a'+1 == pre[1] && !vispre[1])
            vispre[1] = true,idpre[++cpre] = 1;
        if(val[u]-'a'+1 == sub[len] && !vissub[len])
        {
            if(vispre[len])
                ans = true;
            vissub[len] = true,idsub[++csub] = len;
        }
        int v;
        for(int i = head[u];i != -1;i = edg[i].nxt)
        {
            v = edg[i].v;
            if(vis[v]) continue;
            cnt = 0;
            getdis(v,u,val[u]-'a'+1,1);
            for(int j = 1;j <= cnt;++j)
            {
                if(dis[j].hs == pre[dis[j].dep] && vissub[dis[j].dep])
                    ans = true;
                if(dis[j].hs == sub[len-dis[j].dep+1] && vispre[len-dis[j].dep+1])
                    ans = true;
            }
            for(int j = 1;j <= cnt;++j)
            {
                if(dis[j].hs == pre[dis[j].dep] && !vispre[dis[j].dep])
                    vispre[dis[j].dep]= true,idpre[++cpre] = dis[j].dep;
                if(dis[j].hs == sub[len-dis[j].dep+1] && !vissub[len-dis[j].dep+1])
                    vissub[len-dis[j].dep+1] = true,idsub[++csub] = len-dis[j].dep+1;
            }
        }
        for(int i = 1;i <= cpre;++i)
            vispre[idpre[i]] = false;
        for(int i = 1;i <= csub;++i)
            vissub[idsub[i]] = false;
        for(int i = head[u];i != -1;i = edg[i].nxt)
        {
            v = edg[i].v;
            if(vis[v]) continue;
            ms = INF;
            Size = sz[v] < sz[u] ? sz[v]:(ssize-sz[u]);
            getroot(v,v);
            solve(root,Size);
        }
    }
    inline void init()
    {
        ms = INF,Size = n;
        memset(vis,false,sizeof(bool)*(n+1));
        memset(head,-1,sizeof(int)*(n+1));
        tot = 0;
        ans = false;
    }
    inline void inithash()
    {
        pw[0] = 1,pre[0] = sub[len+1] = 0;
        for(int i = 1;i <= len;++i)
        {
            pw[i] = pw[i-1] * P;
            pre[i] = pre[i-1] * P + s[i] - 'a' + 1;
            sub[len-i+1] = sub[len-i+2] * P + s[len-i+1] - 'a' + 1;
        }
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        for(int cas = 1;cas <= t;++cas)
        {
            scanf("%d",&n);
            init();
            int u,v;
            for(int i = 1;i < n;++i)
            {
                scanf("%d%d",&u,&v);
                addedg(u,v),addedg(v,u);
            }
            scanf("%s%s",val+1,s+1);
            len = strlen(s+1);
            inithash();
            getroot(1,1);
            solve(root,Size);
            printf("Case #%d: ",cas);
            if(ans)
                printf("Find
    ");
            else
                printf("Impossible
    ");
        }
        return 0;
    }
    
  • 相关阅读:
    csr_matrix参数解析
    SQL删除重复数据(根据多个字段),pandas的nan存入数据库报错
    XGBoost参数中文翻译以及参数调优
    pandas.DataFrame.quantile
    pandas.DataFrame.rank
    JOIN子句
    ORDER BY子句
    WHERE子句
    SELECT语句
    数据分析-基础
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14738449.html
Copyright © 2020-2023  润新知