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

 

posted @ 2017-04-25 22:08  ihopenot  阅读(168)  评论(0编辑  收藏  举报