zoukankan      html  css  js  c++  java
  • BZOJ 4460 [Jsoi2013]广告计划 ——Bitset 后缀自动机

    发现n比较小,直接枚举答案,然后发现连续的一段是确定的,然后我们只需要判断每个位置是否有这个连续的一段就好了

    发现起点不同,最后的位置可能会有差距,所以DP一下就好了

    然后用0表示未折返,1表示从最下面换到最上面,然后就是发现所有位置互不干扰,直接用Bitset压一下就可以做了

    复杂度N^3/64

    #include <bits/stdc++.h>
    using namespace std;
      
    #define maxn 100005
    int fa[maxn],go[maxn][26],last,cnt,l[maxn],v[maxn],q[maxn];
    char s[maxn];
    bitset <205> bit[maxn],Nothing,dp[2][2];
      
    void init()
    {
        last=cnt=1;
    }
      
    void add(int x,int pos)
    {
        int p=last,q;
        if ((q=go[p][x])){
            if (l[q]==l[p]+1) last=q;
            else{
                int nq=++cnt;
                l[nq]=l[p]+1;
                memcpy(go[nq],go[q],sizeof go[q]);
                fa[nq]=fa[q];
                fa[q]=nq;
                for (;p&&go[p][x]==q;p=fa[p]) go[p][x]=nq;
                last=nq;
            }
        }
        else{
            int np=++cnt; l[np]=l[p]+1;
            for (;p&&!go[p][x];p=fa[p]) go[p][x]=np;
            if (!p) fa[np]=1;
            else{
                q=go[p][x];
                if (l[q]==l[p]+1) fa[np]=q;
                else {
                    int nq=++cnt;
                    l[nq]=l[p]+1;
                    memcpy(go[nq],go[q],sizeof go[q]);
                    fa[nq]=fa[q];
                    fa[q]=fa[np]=nq;
                    for (;p&&go[p][x]==q;p=fa[p]) go[p][x]=nq;
                }
            }
            last=np;
        }
        bit[last][pos]=1;
    }
      
    void insert()
    {
        last=1;
        scanf("%s",s+1);
        int Len=strlen(s+1);
        for (int i=1;i<=Len;++i){
            add(s[i]-'a',i);
        }
    }
      
    void Radix()
    {
        for (int i=1;i<=cnt;++i) v[l[i]]++;
        for (int i=1;i<=cnt;++i) v[i]+=v[i-1];
        for (int i=cnt;i>=1;--i) q[v[l[i]]--]=i;
        for (int i=cnt;i>=1;--i)
            bit[fa[q[i]]]|=bit[q[i]];
    }
      
    int n,m,Len;
    char t[maxn];
      
      
    bool test(int x)
    {
        int now=1,pre=0;
        dp[now][0].reset();
        dp[now][1].reset();
        dp[now][0].set();
        int all=(Len+x-1)/x;
        for (int i=1;i<=x;++i){
            int pos=1,flag=1,tmp=0;
            now^=1; pre^=1;
            for (int j=i;j<=Len;j+=x){
                pos=go[pos][t[j]-'a'];
                tmp++;
                if (!pos) {flag=0;break;}
            }
            if (flag){
                bitset<205> Match=bit[pos];
                if (tmp<all) Match<<=1;
                dp[now][0]=dp[pre][0]&Match;
                dp[now][1]=dp[pre][1]&Match;
                dp[now][1]=(dp[pre][1]|(dp[pre][0]<<1))&Match;
            }
            else{
                return false;
            }
        }
        if (dp[now][0].count()||dp[now][1].count()) return true;
        else return false;
    }
      
    int main()
    {
        #ifdef WXL
        freopen("in.txt","r",stdin);
        #endif
          
        init();
        scanf("%d%d",&n,&m);
        for (int i=1;i<=n;++i){
            insert();
        }
          
        bitset<205> Test;
          
        Radix();
          
        Nothing.reset();
        scanf("%s",t+1);
        Len=strlen(t+1);
        for (int i=1;i<=Len;++i){
            if (test(i)) {
                printf("%d
    ",i);
                return 0;
            }
        }
        printf("No Sulotion
    ");
    }
    

      

  • 相关阅读:
    Java编译期和运行期
    深入理解重载和重写及与之相关的多态性 Overloading and Overriding(转)
    Java编译期优化与运行期优化技术浅析
    JAVA反射
    JSP笔记(二)
    JSP笔记(一)
    字符串之String类
    JAVA的Random类介绍
    (转)详细分析css float 属性
    协议与委托
  • 原文地址:https://www.cnblogs.com/SfailSth/p/7133840.html
Copyright © 2011-2022 走看看