• 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;
    }          
  • 相关阅读:
    ubuntu安装后做得几件事情 【robby_chan】
    malloc函数的一种简单的原理性实现[转]
    了解B树 B+树
    win下格式转为utf8 编码 转码
    log4j2与slf4j日志桥接
    java获取当前行数
    java获取服务器ip地址解决linux上为127.0.0.1的问题
    log4j2的基本使用
    navicator使用之mysql
    log4j与log4j2日志文件的操作
  • 原文地址:https://www.cnblogs.com/lsyyy/p/11606558.html
Copyright © 2020-2023  润新知