其他分享
首页 > 其他分享> > Prefix Free Code 结题报告

Prefix Free Code 结题报告

作者:互联网

Consider nn initial strings of lower case letters, where no initial string is a prefix of any other initial string. Now, consider choosing kk of the strings (no string more than once), and concatenating them together. You can make this many such composite strings:

n×(n−1)×(n−2)×…×(n−k+1)n×(n−1)×(n−2)×…×(n−k+1)

Consider sorting all of the composite strings you can get via this process in alphabetical order. You are given a test composite string, which is guaranteed to belong on this list. Find the position of this test composite string in the alphabetized list of all composite strings, modulo 109+7109+7. The first composite string in the list is at position 11.

Input

Each input will consist of a single test case. Note that your program may be run multiple times on different inputs. Each test case will begin with a line with two integers, first nn and then kk (1≤k≤n1≤k≤n), where nn is the number of initial strings, and kk is the number of initial strings you choose to form composite strings. The upper bounds of nn and kk are limited by the constraints on the strings, in the following paragraphs.

Each of the next nn lines will contain a string, which will consist of one or more lower case letters a..za..z. These are the nn initial strings. It is guaranteed that none of the initial strings will be a prefix of any other of the initial strings.

Finally, the last line will contain another string, consisting of only lower case letters a..za..z. This is the test composite string, the position of which in the sorted list you must find. This test composite string is guaranteed to be a concatenation of kk unique initial strings.

The sum of the lengths of all input strings, including the test string, will not exceed 106106 letters.

Output

Output a single integer, which is the position in the list of sorted composite strings where the test composite string occurs. Output this number modulo 109+7109+7.

Sample Input 1 Sample Output 1
5 3
a
b
c
d
e
cad
26
Sample Input 2 Sample Output 2
8 8
font
lewin
darko
deon
vanb
johnb
chuckr
tgr
deonjohnbdarkotgrvanbchuckrfontlewin
1

题目大意:

      给你N个单词,从中选K个单词组合成一个句子,问这个句子是所有由K个单词组成的句子中的第几个。

解题过程:

     一开始最简单的思路是,看所给句子中的单词是所有单词中的第一几个,然后根据常用的排列组合求解,但是这道题单纯的用数组储存所有单词在进行单词是所有单词中的第几个时会大大的增加时间复杂度,即使对单词进行排序后,还有就是我们需要不断的进行所使用单词的更新,因为先使用的单词会对后面单词的计算构成影响,所以这道题就要求我们使用两种数据结构,一种是字典树,一种是线段树或者树状数组。这道题涉及的知识点以及它的应用还有最后排列组合的应用都十分的好,虽然卡的时间很长,但还是收获非常的多,希望学习完知识点后尝试自己解决。

树状数组:https://blog.csdn.net/NCC__dapeng/article/details/88011188

字典树:https://blog.csdn.net/NCC__dapeng/article/details/87944507

线段树:https://blog.csdn.net/NCC__dapeng/article/details/88011424

下面给出AC代码,其中会附带一些必要的解释,注意这道题的一个小坑点就是,排列组合计算的数组必须开long long 否则会在运算过程中出现溢出的问题:

#include <bits/stdc++.h>
typedef long long ll;
using namespace std;
const int maxn=1e6+100;
const int INF=0x3f3f3f3f;
const ll mod=1e9+7;
int c[maxn];
int n,k,cnt=1;//cnt用来记录在所有单词中的字典序
ll sum=1,fac[maxn];
string str[maxn];

//树状数组

int lowbit(int x)
{
    return x&-x;
}

void update(int x,int val)
{
    while(x<=n)
    {
        c[x]+=val;
        x+=lowbit(x);
    }
}

int getsum(int x)
{
    int res=0;
    while(x>0)
    {
        res+=c[x];
        x-=lowbit(x);
    }
    return res;
}


//字典树

struct TireTree
{
    int idex;
    TireTree *next[26];
    TireTree()
    {
        idex=-1;
        memset(next,0,sizeof(next));
    }
}*root;


void init()
{
    root=new TireTree();

    fac[0]=1;
    fac[1]=n-k+1;
    for(int i=2;i<=k;i++)
    {
        fac[i]=fac[i-1]*(n-k+i)%mod;
    }

}

void BuildTire(string s)
{
    TireTree *p=root;
    int len=s.size();
    for(int i=0;i<len;i++)
    {
        if(p->next[s[i]-'a']==NULL)
        {
            p->next[s[i]-'a']=new TireTree();
        }
        p=p->next[s[i]-'a'];
    }
    p->idex=cnt++;
}

void SearchTireTree(string s)
{
    TireTree *p=root;
    int ans=k-1;
    int len=s.size();
    for(int i=0;i<len;i++)
    {

        p=p->next[s[i]-'a'];
        if(p->idex!=-1)
        {
            sum=(fac[ans--]*(p->idex-getsum(p->idex)-1)+sum)%mod;
            update(p->idex,1);
            p=root;
        }
    }
}


int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>k;
    init();
    for(int i=0;i<n;i++) cin>>str[i];
    sort(str,str+n);

    for(int i=0;i<n;i++) BuildTire(str[i]);

    string strm; cin>>strm;
    SearchTireTree(strm);

    cout<<sum<<endl;

    return 0;

}

 

标签:Code,string,int,initial,单词,composite,Prefix,结题,strings
来源: https://blog.csdn.net/NCC__dapeng/article/details/88010863