zoukankan      html  css  js  c++  java
  • HDU

    求一个串至少包含k个给定的串的方案数(k个串可相互覆盖-所以只能用AC自动机了)

    状态压缩使每个串唯一(1<<i第i个串),防止重复加!(WA)

    #include<cstdlib>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<stack>
    #include<vector>
    #define tree int o,int l,int r
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    #define lo o<<1
    #define ro o<<1|1
    #define pb push_back
    #define mp make_pair
    #define inf 0x7fffffff
    #define eps 1e-7
    #define N 105
    #define M 26
    #define mod 20090717
    using namespace std;
    int m,n,T,t,k;
    int ch[N][M];
    int v[N];
    int f[N],last[N],num;
    int d[N][M][1<<10],ans,ep[M];
    void clear()//Trie树初始化
    {
        num=1;
        ans=0;
        memset(d,-1,sizeof(d));
        memset(ch[0],0,sizeof(ch[0]));
        memset(v,0,sizeof(v));
        memset(last,0,sizeof(last));
    }
    int idx(char c)
    {
        return c-'a';
    }
    void insert(char str[],int val)//建Trie树
    {
        int len=strlen(str);
        int u=0;
        for (int i=0; i<len; ++i )
        {
            int c=idx(str[i]);
            if(!ch[u][c])//保存的是结点坐标
            {
                memset(ch[num],0,sizeof(ch[num]));
                ch[u][c]=num++;//
            }
            u=ch[u][c];
        }
        v[u]+=(1<<val);//唯一标记一个字符串(+=)
    }
    void getac()
    {
        queue<int> q;//保存的节点下标
        f[0]=0;
        for (int c=0; c<M; ++c )
        {
            int u=ch[0][c];
            if(u)//不需要优化的else
            {
                q.push(u);
                f[u]=0;
                last[u]=v[u];//WA
            }
        }
        while(!q.empty())
        {
            int r=q.front();
            q.pop();
            for (int c=0; c<M; ++c )//注意:c表示节点值,不是结点位置
            {
                int u=ch[r][c];
                if(u)
                {
                    q.push(u);
                    int s=f[r];
                    f[u]=ch[s][c];
                    last[u]=(v[u]+last[f[u]]);
                }
                else //重要优化
                    ch[r][c]=ch[f[r]][c];
            }
        }
    }
    char str[20];
    int bit(int x)
    {
        return x==0?0:(bit(x>>1)+(x&1));
    }
    int dp(int u,int sub,int num)
    {
        if(sub==n)
            return bit(num)>=k;
        int &ans=d[u][sub][num];
        if(ans!=-1)return ans;
        if(bit(num)>=k)//优化!!否则TLE(dp时也是需要优化的!)
        {
            ans=ep[n-sub];return ans;
        }
        ans=0;
        for(int i=0;i<26;i++)
        {
            int c=ch[u][i];
            ans+=dp(c,sub+1,num+(last[c]^(last[c]&num)));
            ans%=mod;
        }
        return ans;
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("ex.in","r",stdin);
    #endif
        ep[0]=1;
        for(int i=1;i<=25;i++)
        ep[i]=(ep[i-1]*26)%mod;
        while(scanf("%d%d%d%*c",&n,&m,&k)==3)
        {
            if(!n&&!m&&!k)return 0;
            clear();
            int i=0;
            while(m--)
            {
                scanf("%s",str);
                insert(str,i++);
            }
            getac();
            printf("%d
    ",dp(0,0,0));
        }
        return 0;
    }
    View Code
  • 相关阅读:
    百度地图 如何制作泡泡放大镜?
    百度地图 孪生姐妹地图
    百度地图Api进阶教程-点聚合9.html
    百度地图Api进阶教程-实例高级操作8.html
    百度地图Api进阶教程-用户自定义数据(标记和搜索)7.html
    百度地图Api进阶教程-地图鼠标左右键操作实例和鼠标样式6.html
    百度地图Api进阶教程-弹出信息窗口5.html
    百度地图Api进阶教程-点击生成和拖动标注4.html
    app设计需注意的
    JS移动客户端--触屏滑动事件 banner图效果
  • 原文地址:https://www.cnblogs.com/sbaof/p/3374792.html
Copyright © 2011-2022 走看看