poj 1625 Censored! 夜

http://poj.org/problem?id=1625

AC自动机+DP+高精度

高精度的部分用c++里面的重载就可以

从树上节点转移到另一节点时 对其可行性的求解一定要注意

代码:

#include<iostream>
#include<cmath>
#include<cstdio>
#include<string>
#include<cstring>
#include<vector>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<algorithm>

#define LL long long

using namespace std;

const int INF=0x3f3f3f3f;
const int MOD=20090717;
const LL LMOD=100000;
const int N=55;
const int M=135;
const int K=50;
class BigInteger
{
public:
    BigInteger()
    {
        memset(bint,0,sizeof(bint));
        D=1000000000;
        len=1;
    }
    BigInteger(int x)
    {
        memset(bint,0,sizeof(bint));
        bint[0]=x;
        D=1000000000;
        len=1;
    }
    BigInteger operator +(const BigInteger &x)
    {
        BigInteger y;
        int l;
        for(l=0;l<x.len||l<len;++l)
        y.bint[l]=x.bint[l]+bint[l];
        y.len=l;
        for(l=0;l<y.len;++l)
        if(y.bint[l]>=D)
        {++y.bint[l+1];y.bint[l]-=D;}
        if(y.bint[l]>0)
        ++y.len;
        return y;
    }
    //friend ostream& operator <<(ostream& output,const BigInteger& x);
    int bint[50];
    int len;
    int D;
};
struct nodeTrie
{
    int v;
    int fail;
    int next[K];
    void initialize()
    {
        v=0;
        fail=-1;
        memset(next,-1,sizeof(next));
    }
}trie[M];
int cnt,root;
char s[N];
int to[M][K];
BigInteger dp[N][M];
map<char,int>mt;
int getNewNode()
{
    ++cnt;
    trie[cnt].initialize();
    return cnt;
}
void addWord(int p,char *s,int k)
{
    if(s[0]=='\0') return ;
    for(int i=0;s[i]!='\0';++i)
    {
        if(trie[p].next[mt[s[i]]]==-1)
        trie[p].next[mt[s[i]]]=getNewNode();
        p=trie[p].next[mt[s[i]]];
    }
    trie[p].v=k;
}
void init(int p)
{
    gets(s);//puts(s);
    //scanf("%s",s);
    int n=strlen(s);
    for(int i=0;i<n;++i)
    mt[s[i]]=i;
    for(int i=0;i<n;++i)
    mt[s[i]]=i;
    cnt=0;
    root=getNewNode();
    for(int i=1;i<=p;++i)
    {
        gets(s);
        //scanf("%s",s);
        addWord(root,s,1);
    }
}
void bfs(int p)
{
    trie[p].fail=root;
    queue<int>qt;
    qt.push(p);
    while(!qt.empty())
    {
        int y;
        int x=qt.front();qt.pop();
        for(int i=0;i<K;++i)
        if(trie[x].next[i]!=-1)
        {
            qt.push(trie[x].next[i]);
            if(x==root)
            {trie[trie[x].next[i]].fail=root;continue;}
            y=trie[x].fail;
            while(y!=root&&trie[y].next[i]==-1)
            y=trie[y].fail;
            if(trie[y].next[i]!=-1)
            trie[trie[x].next[i]].fail=trie[y].next[i];
            else
            trie[trie[x].next[i]].fail=root;
            trie[trie[x].next[i]].v|=trie[trie[trie[x].next[i]].fail].v;
        }
    }
}
void makeTo(int n,int k)
{
    for(int i=1;i<=n;++i)
    for(int j=0;j<k;++j)
    {
        int p=i;
        while(p!=root&&trie[p].next[j]==-1)
        p=trie[p].fail;
        if(trie[p].next[j]!=-1)
        to[i][j]=trie[p].next[j];
        else
        to[i][j]=root;
    }

};
int main()
{

    //freopen("data.in","r",stdin);
    int n,m,p;
    scanf("%d %d %d ",&n,&m,&p);
    init(p);
    bfs(root);
    makeTo(cnt,n);
    dp[0][1]=BigInteger(1);
    for(int i=0;i<m;++i)
    for(int j=1;j<=cnt;++j)
    {
        for(int l=0;l<n;++l)
        {
            int r=to[j][l];
            if(trie[r].v==1)
            continue;
            dp[i+1][r]=dp[i+1][r]+dp[i][j];
            //cout<<(i+1)<<" "<<r<<endl;
            //cout<<dp[i+1][r]<<endl;
        }
    }
    BigInteger ans;
    for(int j=0;j<=cnt;++j)
    ans=ans+dp[m][j];
    printf("%d",ans.bint[ans.len-1]);
    for(int i=ans.len-2;i>=0;--i)
    printf("%09d",ans.bint[i]);
    printf("\n");
    return 0;
}

  

原文地址:https://www.cnblogs.com/liulangye/p/2985892.html