Consider n initial strings of lower case letters, where no initial string is a prefix of any other initial string. Now, consider choosing k 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)

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 10^9 + 7. The first composite string in the list is at position 1.

Input Format

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 k(1≤k≤n), where n is the number of initial strings, and k is the number of initial strings you choose to form composite strings. The upper bounds of nnand k are limited by the constraints on the strings, in the following paragraphs.

Each of the next n lines will contain a string, which will consist of one or more lower case letters a..z. These are the n 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..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 k unique initial strings.

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

Output Format

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 10^9 + 7.

样例输入1

  1. 5 3
  2. a
  3. b
  4. c
  5. d
  6. e
  7. cad

样例输出1

  1. 26

样例输入2

  1. 8 8
  2. font
  3. lewin
  4. darko
  5. deon
  6. vanb
  7. johnb
  8. chuckr
  9. tgr
  10. deonjohnbdarkotgrvanbchuckrfontlewin

样例输出2

  1. 12451

题意

n个串任取k个,n个串互不为前缀,排序后,查询字符串所在的排名。

题解

可以知道查询的字符串唯一组成,假设为s1s2s3....sk,s1的排名为rk1。

那么答案ans=rk1*A(n-1,k-1)+rk2*A(n-2,k-2)+...+rkk*A(n-k,0)。

那么rk可以通过字典树知道,它真正的排名还需要减掉前面出现过的,这个用树状数组维护。

最后组合数预处理一下就行了。

代码

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int N=;
  4. const int MD=;
  5. struct node{
  6. int v;
  7. node *nxt[];
  8. node()
  9. {
  10. v=;
  11. for(int i=;i<;i++)nxt[i]=NULL;
  12. }
  13. };
  14. node *root;
  15. void ins(string s,int pos)
  16. {
  17. node *pre=root,*now;
  18. int l=s.size();
  19. for(int i=;i<l;i++)
  20. {
  21. int id=s[i]-'a';
  22. now=pre->nxt[id];
  23. if(now==NULL)
  24. {
  25. now=new node;
  26. pre->nxt[id]=now;
  27. }
  28. pre=now;
  29. }
  30. pre->v=pos;
  31. }
  32. vector<string> vec;
  33. string s,ss;
  34. int a[N],n,k,f[N],inv[N];
  35. void add(int p,int x) {
  36. while(p<=n)
  37. a[p]=a[p]+x,p+=(p&-p);
  38. }
  39. int query(int p) {
  40. int ans=;
  41. while(p>)
  42. ans=ans+a[p],p-=(p&-p);
  43. return ans;
  44. }
  45. int quick_pow(int x,int y) {
  46. int ans=;
  47. while(y) {
  48. if(y&) ans=1LL*ans*x%MD;
  49. y>>=;
  50. x=1LL*x*x%MD;
  51. }
  52. return ans;
  53. }
  54. void init() {
  55. f[]=;
  56. for(int i=;i<=n;i++) f[i]=1LL*f[i-]*i%MD;
  57. inv[n]=quick_pow(f[n],MD-);
  58. for(int i=n-;i>=;i--) inv[i]=1LL*inv[i+]*(i+)%MD;
  59. }
  60. int main() {
  61. ios::sync_with_stdio(false),cin.tie(),cout.tie();
  62. root=new node;
  63. cin>>n>>k,init();
  64. for(int i=;i<n;i++) cin>>s,vec.push_back(s);
  65. sort(vec.begin(),vec.end());
  66. for(int i=;i<n;i++) ins(vec[i],i+);
  67. for(int i=;i<n;i++) add(i+,);
  68. cin>>s;
  69. int ans=,t,p=;
  70. node *pre=root,*now;
  71. for(int i=;s[i];i++) {
  72. int id=s[i]-'a';
  73. now=pre->nxt[id];
  74. pre=now;
  75. if(now->v>)
  76. {
  77. t=now->v;
  78. add(t,-);
  79. p++;
  80. ans=(ans+1LL*query(t)*f[n-p]%MD*inv[n-k]%MD)%MD;
  81. pre=root;
  82. }
  83. }
  84. cout<<ans<<'\n';
  85. return ;
  86. }

计蒜客 Prefix Free Code(字典树+树状数组)的更多相关文章

  1. 计蒜客 青出于蓝胜于蓝(dfs序+树状数组)

    题目描述 武当派一共有 n 人,门派内 n 人按照武功高低进行排名,武功最高的人排名第 1,次高的人排名第 2,... 武功最低的人排名 第 n.现在我们用武功的排名来给每个人标号,除了祖师爷,每个人 ...

  2. 计蒜客 31451 - Ka Chang - [DFS序+树状数组][2018ICPC沈阳网络预赛J题]

    题目链接:https://nanti.jisuanke.com/t/31451 Given a rooted tree ( the root is node $1$ ) of $N$ nodes. I ...

  3. 计蒜客 38229.Distance on the tree-1.树链剖分(边权)+可持久化线段树(区间小于等于k的数的个数)+离散化+离线处理 or 2.树上第k大(主席树)+二分+离散化+在线查询 (The Preliminary Contest for ICPC China Nanchang National Invitational 南昌邀请赛网络赛)

    Distance on the tree DSM(Data Structure Master) once learned about tree when he was preparing for NO ...

  4. 计蒜客16492 building(二分线段树/分块)

    题解: 考虑用线段树维护楼的最大值,然后这个问题就很简单了. 每次可以向左二分出比x高的第一个楼a,同理也可以向右二分出另一个楼b,如果a,b都存在,答案就是b-a-1. 注意到二分是可以直接在线段树 ...

  5. 计蒜客 28449.算个欧拉函数给大家助助兴-大数的因子个数 (HDU5649.DZY Loves Sorting) ( ACM训练联盟周赛 G)

    ACM训练联盟周赛 这一场有几个数据结构的题,但是自己太菜,不会树套树,带插入的区间第K小-替罪羊套函数式线段树, 先立个flag,BZOJ3065: 带插入区间K小值 计蒜客 Zeratul与Xor ...

  6. 爬虫acm比赛成绩(多页成绩整合在一起、获取复制不了的数据)(hihocoder、计蒜客)

    https://github.com/congmingyige/web-crawler_rank-of-competition-in-JiSuanKe-and-hihocoder 1. 计蒜客(获取复 ...

  7. 计蒜客 NOIP 提高组模拟竞赛第一试 补记

    计蒜客 NOIP 提高组模拟竞赛第一试 补记 A. 广场车神 题目大意: 一个\(n\times m(n,m\le2000)\)的网格,初始时位于左下角的\((1,1)\)处,终点在右上角的\((n, ...

  8. 计蒜客 A1607 UVALive 8512 [ACM-ICPC 2017 Asia Xi'an]XOR

    ICPC官网题面假的,要下载PDF,点了提交还找不到结果在哪看(我没找到),用VJ交还直接return 0;也能AC 计蒜客题面 这个好 Time limit 3000 ms OS Linux 题目来 ...

  9. [计蒜客] 矿石采集【记搜、Tarjan缩点+期望Dp】

    Online Judge:计蒜客信息学3月提高组模拟赛 Label:记搜,TarJan缩点,树状数组,期望Dp 题解 整个题目由毫无关联的两个问题组合成: part1 问题:对于每个询问的起点终点,求 ...

随机推荐

  1. linux和window环境下安装ruby和sass

    linux下安装ruby 下载linux的ruby安装包    http://www.ruby-lang.org/en/downloads/ 将ruby安装包在linux环境下解压    tar -x ...

  2. js 面向对象几种数据模式

    一.单例模式: 把描述同一事物的属性和方法放在同一内存空间下,实现了分组的作用,防止同一属性或者方法冲突.我们把这种分组编写代码的模式叫做单例模式即普通的对象. 单例模式是项目开发中最常用的一种开发模 ...

  3. iOS开发CGImage.h简介

    1.前因 由于剪切图片用到下面方法,此方法属于CGImage.h中,通过创建CGImageRef像素位图,可以通过操作存储的像素位来编辑图片. /* Create an image using the ...

  4. MySQL中修改多个数据表的字段拼接问题

    错误1: 异常:Truncated incorrect DOUBLE value: 'lili' 问题分析:我的修改sql语句是:update video set vname='汉字' and vdi ...

  5. 高德地图(AMap)JavaScript API的使用

    申请JSAPI的开发者key 申请地址:http://lbs.amap.com/dev/key 引入高德地图JavaScript API文件: <script type="text/j ...

  6. object and namespace

    http://effbot.org/zone/python-objects.htm 几点总结: (1) 类的基本属性 . id, returned by id(obj) . type, returne ...

  7. 实习面试总结(只写了昨天腾讯的面试和拿到offer的一个小公司, 有空再把前面的补上吧)

    一个月来面了大大小小的公司有近10个,还是总结一下吧,希望对大家有点用处. 我想说的是,大学四年,如果不会继续读研深造,那么你需要做的不仅仅是疯狂的做项目,或者单独的学算法. 最好的方式就是都了解一点 ...

  8. MATLAB技巧—sort和sortrows函数

    MATLAB技巧-sort和sortrows函数 1.sort函数 sort函数用于对数据进行排序,通过help sort命令,可以查找到sort函数的具体用法: Y = SORT(X,DIM,MOD ...

  9. Java程序员面试题收集(4)

    Java面试题和答案JAVA相关基础知识1.面向对象的特征有哪些方面      1.抽象:抽象就是忽略一个主题中与当前目标无关的那些方面,以便更充分地注意与当前目标有关的方面.抽象并不打算了解全部问题 ...

  10. HDFS 数据存取策略