zoukankan      html  css  js  c++  java
  • prefix free code

    其实总的感觉也不是很难

    就是昨天看到第二题就放弃了

    简单来说就是组合数学一点点+字典树一点点

    像是一个数位dp

    #include<bits/stdc++.h>
    #define re return
    #define inc(i,l,r) for(ll i=l;i<=r;++i)
    using namespace std;
    template<typename T>inline void rd(T&x)
    {
        char c;bool f=0;
        while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
        x=c^48;
        while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
        if(f)x=-x;
    }
    
    #define ll long long 
    ll n,k;
    const int maxn=1000005,mod=1e9+7;
    ll tot,tr[maxn][27],ed[maxn],cnt[maxn];
    char s[maxn];
    
    inline void insert()
    {
        ll len=strlen(s+1);
        ll rt=0;
        inc(i,1,len)
        {
            if(!tr[rt][s[i]-'a'])
                tr[rt][s[i]-'a']=++tot;
            rt=tr[rt][s[i]-'a'];
        }
        ed[rt]=1;
        ++cnt[rt];
    }
    
    inline void dfs(ll rt)
    {
    
        if(ed[rt])re;
        inc(i,0,25)
        if(tr[rt][i])
        {
            dfs(tr[rt][i]);
            cnt[rt]+=cnt[tr[rt][i]];
        }    
        
    }
    ll slen,st=1;
    ll jc[maxn],jcinv[maxn],ans,Ans,CNT;
    
    inline void find(ll rt)
    {
        
        if(ed[rt])
        {
            Ans=(Ans+jc[n-CNT]*jcinv[n-k]%mod*ans%mod)%mod;
            cnt[rt]--;
            re ; 
        }
        ll x=s[st]-'a';
        inc(i,0,25)
        if(i<x)
        {
            if(tr[rt][i])ans+=cnt[tr[rt][i]];
                   //因为下标从0开始
        }
        else 
        {
            ++st;
            find(tr[rt][x]);
            cnt[rt]--;
            re ;
        }
    
    }
    
    inline void Get_jc()
    {
        jcinv[0]=jcinv[1]=jc[1]=jc[0]=1; 
        inc(i,2,n)
        {
            jc[i]=jc[i-1]*i%mod;
            jcinv[i]=(mod-mod/i)*jcinv[mod%i]%mod;
        }
        inc(i,2,n)jcinv[i]=jcinv[i-1]*jcinv[i]%mod;
    }
    
    int main()
    {
        freopen("in.txt","r",stdin);
        rd(n),rd(k);
        inc(i,1,n)
        {
            scanf("%s",s+1);
            insert();
        }
        
        dfs(0);
        
        Get_jc();
        
        scanf("%s",s+1);
        while(CNT<k)
        {
            ++CNT;
            ans=0;
            find(0);
        }    
        
        printf("%lld",(Ans+1)%mod);
        re 0;
    }          
  • 相关阅读:
    Form表单提交数据的几种方式
    前端基础-HTML
    python入门函数详解
    Python作业编写
    Python入门数据类型详解
    Jquery选择器
    做外链接和有外链接区别
    三层架构
    drop,delete,truncate区别
    run()和star()区别
  • 原文地址:https://www.cnblogs.com/lsyyy/p/11606558.html
Copyright © 2011-2022 走看看