Bzoj4212--神牛养成计划

Posted ihopenot

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Bzoj4212--神牛养成计划相关的知识,希望对你有一定的参考价值。

正规题解传送门 : https://zyqn.tech/?p=3163

但是我们发现n只有2000,于是可以建出trie树然后愉快的bitset去搞。

直接对于trie上每个节点开个bitset空间爆炸。但是有很多是重复的,所以我们想虚树一样建,每个节点只存一个link指针。

代码 : 

技术分享
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define eps 1e-9
#define LL long long
using namespace std;

#define int int
inline int Max(int a,int b) {return a>b?a:b;}
inline int Min(int a,int b) {return a<b?a:b;}
inline int Sqr(int a) {return a*a;}
inline int Abs(int a) {return a>0?a:-a;}
#undef int

#define MAXN 2000006

int n,m,ans;
bitset<2005> x,pol[100005];int tot;
char s[MAXN];

struct Trie{
    int tra[MAXN][27],lk[MAXN],cnt;
    void Init() {
        memset(tra,0,sizeof(tra));
        cnt=1;
    }
    
    void Build(int v) {
        int fr=0;
        for(int i=0;i<27;i++) {
            if(!tra[v][i]) continue;
            Build(tra[v][i]);
            if(!fr) lk[v]=lk[tra[v][i]],fr=1;
            else if(fr==1) {
                tot++;pol[tot]=pol[lk[v]];
                pol[tot]|=pol[lk[tra[v][i]]];
                lk[v]=tot;fr=2;
            }
            else pol[lk[v]]|=pol[lk[tra[v][i]]];
        }
    }
    
    void Insert(int k,char *s,int len) {
        int now=1;
        for(int i=0;i<len;i++) {
            if(!tra[now][s[i]-a]) now=tra[now][s[i]-a]=++cnt;
            else now=tra[now][s[i]-a];
        }
        if(!lk[now]) lk[now]=++tot;
        pol[lk[now]][k]=1;
    }
    int Patten(char *s,int len) {
        int now=1;
        for(int i=0;i<len;i++) {
            if(!tra[now][s[i]-a]) return 0;
            now=tra[now][s[i]-a];
        }
        return lk[now];
    }
}hd,bk;

inline void Updata(int n) {
    for(int i=0;i<n;i++) 
        s[i]=((s[i]-a+ans)%26)+a;
}

int main() {
    hd.Init();bk.Init();
    scanf("%d",&n);
    for(int len,i=1;i<=n;i++) {
        scanf("%s",s);
        len=strlen(s);
        hd.Insert(i,s,len);
        reverse(s,s+len);
        bk.Insert(i,s,len);
    }
    hd.Build(1);
    bk.Build(1);
    scanf("%d",&m);
    for(int len,i=1;i<=m;i++) {
        x.set();
        scanf("%s",s);
        len=strlen(s);
        Updata(len);
        x&=pol[hd.Patten(s,len)];
        
        scanf("%s",s);
        len=strlen(s);
        reverse(s,s+len);
        Updata(len);
        x&=pol[bk.Patten(s,len)];
        
        ans=x.count();
        printf("%d\n",ans);
    }
    return 0;
}
View Code

 

以上是关于Bzoj4212--神牛养成计划的主要内容,如果未能解决你的问题,请参考以下文章

爱今天养成计划

2021腾讯犀牛鸟校园布道师养成计划丨百校同行

游戏程序猿养成计划

转游戏程序员养成计划

腾讯犀牛鸟「云开发」校园技术布道师养成计划

python大佬养成计划----HTML DOM