• codeforces727E. Games on a CD


    题意:给一个n*k的循环字符串可能从任意地方断开,然后m个长度k的字符串,问你能不能用下面的字符串(每个最多用一次)构成上面的字符串,能循环移位
    题解:对下面的串建ac自动机,记录字符串最后一个位置,然后把上面的串扩展k个,再在ac自动机上跑确定每个节点能匹配的字符串是谁,然后枚举k个位置作为起点,开始匹配,n个位置能匹配而且不重复即是答案

    //#pragma GCC optimize(2)
    //#pragma GCC optimize(3)
    //#pragma GCC optimize(4)
    //#pragma GCC optimize("unroll-loops")
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define db double
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define ld long double
    //#define C 0.5772156649
    //#define ls l,m,rt<<1
    //#define rs m+1,r,rt<<1|1
    #define pll pair<ll,ll>
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define ull unsigned long long
    //#define base 1000000000000000000
    #define fin freopen("a.txt","r",stdin)
    #define fout freopen("a.txt","w",stdout)
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
    inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
    template<typename T>inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
    template<typename T>inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
    inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
    inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}
    
    using namespace std;
    
    const ull ba=233;
    const db eps=1e-7;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int N=2000000+10,maxn=100000+10,inf=0x3f3f3f3f;
    
    char s[N],p[N];
    int a[N];
    struct ACM{
        int root,tot;
        int Next[N][26],fail[N],End[N];
        int newnode()
        {
            memset(Next[tot],-1,sizeof Next[tot]);
            End[tot]=0;
            return tot++;
        }
        void init(){tot=0;root=newnode();}
        void ins(int id)
        {
            int now=root,n=strlen(s);
            for(int i=0;i<n;i++)
            {
                if(Next[now][s[i]-'a']==-1)Next[now][s[i]-'a']=newnode();
                now=Next[now][s[i]-'a'];
            }
            End[now]=id;
        }
        void build()
        {
            queue<int>q;
            fail[root]=root;
            for(int i=0;i<26;i++)
            {
                if(Next[root][i]==-1)Next[root][i]=root;
                else
                {
                    fail[Next[root][i]]=root;
                    q.push(Next[root][i]);
                }
            }
            while(!q.empty())
            {
                int now=q.front();
                q.pop();
                for(int i=0;i<26;i++)
                {
                    if(Next[now][i]==-1)Next[now][i]=Next[fail[now]][i];
                    else
                    {
                        fail[Next[now][i]]=Next[fail[now]][i];
                        q.push(Next[now][i]);
                    }
                }
            }
        }
        void query(int n,int k)
        {
    //        for(int i=1;i<=tot;i++)
    //        {
    //            printf("%d %d --",i,End[i]);
    //            for(int j=0;j<4;j++)printf("%d ",Next[i][j]);
    //            puts("");
    //        }
            int now=root;
            for(int i=0;p[i];i++)
            {
                now=Next[now][p[i]-'a'];
                a[i]=End[now];
            }
            for(int i=0;i<k;i++)
            {
                now=Next[now][p[i]-'a'];
                a[n*k+i]=End[now];
            }
            for(int i=0;i<k;i++)
            {
                bool ok=1;vi v;
                for(int j=0,l=i+k-1;j<n;l+=k,j++)
                {
                    if(!a[l])ok=0;
                    else v.pb(a[l]);
                }
                if(ok)
                {
                    vi te=v;
                    sort(te.begin(),te.end());te.erase(unique(te.begin(),te.end()),te.end());
                    if(te.size()!=v.size())continue;
                    puts("YES");
                    for(int x:v)printf("%d ",x);
                    puts("");
                    return ;
                }
            }
            puts("NO");
    //        for(int i=0;i<n*k+k;i++)printf("%d ",a[i]);
    //        puts("");
        }
    }ac;
    int main()
    {
        int n,k;scanf("%d%d",&n,&k);
        scanf("%s",p);
        int m;scanf("%d",&m);
        ac.init();
        for(int i=1;i<=m;i++)
        {
            scanf("%s",s);
            ac.ins(i);
        }
        ac.build();
        ac.query(n,k);
        return 0;
    }
    /********************
    
    ********************/
    
  • 相关阅读:
    SQLZOO:SELECT from WORLD Tutorial
    Spyder——小技巧+快捷键
    JDK国内镜像
    debian 安装 plymouth 美化开机动画
    docker 国内镜像加速
    有关npm镜像加速的问题 yarn nvm yrm
    调整vscode工具栏侧边栏字体大小
    github的淘宝代理?
    fcitx5 主题设置
    debian testing安装qemu-kvm和virt-manager
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/10716280.html
Copyright © 2020-2023  润新知