• 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;
    }
    

      

  • 相关阅读:
    呈现系统-组件间的通信方式(7)
    web项目中图标的前端处理方案
    ADO--数据访问技术
    canvas--绘制路径
    canvas--改变颜色
    canvas-在画布中画两个方块(一个空心一个实体)
    canvas--画布《第一步》
    拼图游戏【简单】
    判断字符串是否为空--string.Empty、string=""、s.length==0
    判断Char是否为数字
  • 原文地址:https://www.cnblogs.com/liulangye/p/2985892.html
Copyright © 2020-2023  润新知