It's known to all that ZYB is godlike, so obviously he has a large number of titles, such as jskingjsking, bijingzybbijingzyb and nbazybnbazyb. ZYB likes his titles very much.

Each of ZYB's titles is a string consisting of lower case letters 'a'-'z''a'-'z' associated with a happiness value hihi, which shows how much ZYB likes this title. If you say any substring of some title with happiness value xx, he will get xx happiness points. Moreover, a string may appear in more than one title. In this case, the happiness points ZYB gets are multiplied. If the string you say is not the substring of any of his titles, he gets no happiness point.

For example, let's say ZYB has two titles: zybnbzybnb (with happiness value 3) and ybybybyb (with happiness value 5). If you say yy, bb or ybyb, ZYB will get 15 happiness points; if you say zz, zyzy or zybzyb, ZYB will only get 3 happiness points; if you say ybzybz or ybacybac he will get 0 happiness points.

One day, you find ZYB pretty sad. As a big fan of ZYB, you want to say a word to ZYB to cheer him up. However, ZYB is really busy, so you can only say no more than mm letters. As you haven't seen ZYB for a long time, you are so excited that you forget what you want to say, so you decide to choose to say a nonempty string no longer than mm and only containing 'a'-'z''a'-'z' with equal probability. You want to know the expectations of happiness points you will bring to ZYB for different mm.

InputThe first line contains an integer nn (1≤n≤104)(1≤n≤104), the number of titles ZYB has.

The ii-th of the next nn lines contains a nonempty string titi, which only contains lower case letters 'a'-'z''a'-'z', representing the ii-th title. The sum of lengths of all titles does not exceed 3×1053×105.

Then follows a line with nn integers hihi (1≤hi≤106)(1≤hi≤106), the happiness value of ii-th title.

The next line is a single integer QQ (1≤Q≤3×105)(1≤Q≤3×105), the number of queries.

For the next QQ lines, each contains a single integer mm (1≤m≤106)(1≤m≤106), meaning that you can say no more than mm letters to ZYB.

The input data contains only one test case.OutputFor each query, display a single line of integer, representing the answer. It can be proved that the answer can be uniquely written as p/qp/q where pp and qq are non-negative integers with gcd(p,q)=gcd(q,109+7)=1gcd(p,q)=gcd(q,109+7)=1, and you should display p⋅q−1mod(109+7)p⋅q−1mod(109+7), where q−1q−1 means the multiplicative inverse of qq modulo 109+7109+7.Sample Input

2
zybnb
ybyb
3 5
4
1
2
3
4

Sample Output

769230776
425925929
891125950
633120399

Hint

For the first query, you can bring him 3 happiness points if you say "z" or "n", and 15 happiness points if you say "y" or "b"; all other strings of length 1 bring no
happiness point to ZYB. Therefore, the expectation is (2×3+2×15)/26 = 18/13, and the answer is 18×13^(-1) mod (10^9+7) = 769230776.


题意:

给你n个字符串,然后每个字符串有一个快乐值。然后给你m个询问,每个询问给你一个长度,让你写出一个不大于这个长度的字串。这个字串的权值定义为,如果这个字符串中出现过第i个给定字符串的子串,那么权值乘以第i个字符串的快乐值,最后答案就是多个快乐值相乘。现在问你给定长度的字符串权值的期望。

思路:

由于要用到多个字符串的所有子串,所以我们很容易想到广义SAM.对于一个长度m,那么它的贡献为长度1~m所有子串的贡献和,考虑它的分母就是26,262,263...26m 的和,我们可以预处理出来。考虑它的分子就是后缀自动机上面所有出现的长度小于等于m的子串的贡献和。在后缀自动机中的parent树中,如果p所代表的子串出现的话,那么fa[p]所代表的的子串一定出现,那么len[fa[p]]+1~len[p]的长度都会出现,而且贡献为len[p]的贡献,根据right数组的定义,parent的出现次数要比x多,那么长度介于最长后缀和本身长度之间的后缀的出现次数肯定与x的出现次数相同。如果不同,那么parent肯定会指向第一个不相同的后缀对应的节点。所以说这从parent的长度加一到x的长度,这一整段的贡献我们都要计算上去。我们用一个前缀和数组sum,记录对应长度的贡献。对应的,区间 [len[fa[x]]+1,len[x]] 上的贡献都是y,表现在sum上面就是两个端点一加一减。统计完毕后,对sum求一遍前缀和,之后sum[i]表示所有长度为i的串的贡献。然后再次对sum求一次前缀和,这样的话sum[i]就表示所有长度为1~i的串的贡献。

 

参考代码:

#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
typedef long long ll;
const int maxn=1e6+;
int pw[maxn],n,m;
int flag[maxn],h[maxn],sum[maxn],ans[maxn];
string s[maxn];
bool vis[maxn];
int qpow(int a,int b)
{
int ans=;
while(b)
{
if(b&)ans=(ll)ans*a%mod;
a=(ll)a*a%mod; b>>=;
}
return ans;
}
void Init()
{
pw[]=;
for(int i=;i<maxn;i++)
pw[i]=(ll)pw[i-]*26ll%mod;
for(int i=;i<maxn;i++)
pw[i]=(pw[i]+pw[i-])%mod;
}
struct SAM{
int fa[maxn<<],l[maxn<<],nxt[maxn<<][];
int last,tot;
void Init()
{
last=tot=;
memset(nxt[tot],,sizeof nxt[tot]);
l[tot]=fa[tot]=;
}
int NewNode()
{
++tot;
memset(nxt[tot],,sizeof nxt[tot]);
l[tot]=fa[tot]=;
return tot;
}
void Insert(int ch)
{
int p,q,np,nq;
if(nxt[last][ch])
{
p=last;q=nxt[p][ch];
if(l[q]==l[p]+) last=q;//////
else
{
nq=NewNode();
l[nq]=l[p]+;fa[nq]=fa[q];
memcpy(nxt[nq],nxt[q],sizeof(nxt[q]));
fa[q]=nq;
while(p&&nxt[p][ch]==q) nxt[p][ch]=nq,p=fa[p];
last=nq;//////
}
}
else
{
np=NewNode(),p=last;
last=np; l[np]=l[p]+;
while(p&&!nxt[p][ch]) nxt[p][ch]=np,p=fa[p];
if(!p) fa[np]=;
else
{
q=nxt[p][ch];
if(l[q]==l[p]+) fa[np]=q;
else
{
nq=NewNode();
memcpy(nxt[nq],nxt[q],sizeof nxt[q]);
fa[nq]=fa[q];
l[nq]=l[p]+;
fa[q]=fa[np]=nq;
while(p&&nxt[p][ch]==q) nxt[p][ch]=nq,p=fa[p];
}
}
}
}
void cal(string s,int val,int tag)
{
int cur=;
for(int i=;s[i];i++)
{
cur=nxt[cur][s[i]-'a'];
for(int tmp=cur;tmp&&flag[tmp]!=tag;tmp=fa[tmp])
ans[tmp]=1LL*ans[tmp]*val%mod,flag[tmp]=tag;
}
}
void build(int cur)
{
vis[cur]=;
sum[l[fa[cur]]+]=(sum[l[fa[cur]]+]+ans[cur])%mod;
sum[l[cur]+]=(sum[l[cur]+]-ans[cur]+mod)%mod;
for(int i=;i<;i++)
{
int Nxt=nxt[cur][i];
if(Nxt&&!vis[Nxt]) build(Nxt);
}
}
} sam;
int main()
{
ios::sync_with_stdio();
cin.tie(); cout.tie();
Init(); sam.Init();
cin>>n;
for(int i=;i<=n;++i)
{
cin>>s[i]; sam.last=;
for(int j=;s[i][j];++j)
sam.Insert(s[i][j]-'a');
}
fill(ans,ans+maxn,);
for(int i=;i<=n;++i) cin>>h[i];
for(int i=;i<=n;++i) sam.cal(s[i],h[i],i);
sam.build(); sum[]=;
for(int i=;i<maxn;++i) sum[i]=(sum[i]+sum[i-])%mod;
for(int i=;i<maxn;++i) sum[i]=(sum[i]+sum[i-])%mod;
cin>>m;
while(m--)
{
int k; cin>>k;
cout<<1LL*sum[k]*qpow(pw[k],mod-)%mod<<endl;
}
return ;
}
												

HDU 6405 Make ZYB Happy(广义SAM)的更多相关文章

  1. 【HDU 4436】 str2int (广义SAM)

    str2int Problem Description In this problem, you are given several strings that contain only digits ...

  2. hdu6405Make ZYB Happy 广义sam

    题意:给出n(n<=10000)个字符串S[1~n],每个S[i]有权值val[i],随机等概率造一个由小写字母构成的字符串T,Sum = 所有含有子串T的S[i]的val[i]之积,求Sum的 ...

  3. 【BZOJ 3926】 [Zjoi2015]诸神眷顾的幻想乡 (广义SAM)

    3926: [Zjoi2015]诸神眷顾的幻想乡 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 974  Solved: 573 Descriptio ...

  4. 【BZOJ 3473】 字符串 (后缀数组+RMQ+二分 | 广义SAM)

    3473: 字符串 Description 给定n个字符串,询问每个字符串有多少子串(不包括空串)是所有n个字符串中至少k个字符串的子串? Input 第一行两个整数n,k. 接下来n行每行一个字符串 ...

  5. luogu3346 诸神眷顾的幻想乡 (广义SAM)

    首先,让每一个叶节点做一次树根的话,每个路径一定至少有一次会变成直上直下的 于是对于每个叶节点作为根产生的20个trie树,把它们建到同一个广义SAM里 建法是对每个trie dfs去建,last就是 ...

  6. loj#6031. 「雅礼集训 2017 Day1」字符串(SAM 广义SAM 数据分治)

    题意 链接 Sol \(10^5\)次询问每次询问\(10^5\)个区间..这种题第一感觉就是根号/数据分治的模型. \(K\)是个定值这个很关键. 考虑\(K\)比较小的情况,可以直接暴力建SAM, ...

  7. Luogu P3181 [HAOI2016]找相同字符 广义$SAM$

    题目链接 \(Click\) \(Here\) 设一个串\(s\)在\(A\)中出现\(cnt[s][1]\)次,在\(B\)中出现\(cnt[s][2]\)次,我们要求的就是: \[\sum cnt ...

  8. CF666E Forensic Examination 广义SAM、线段树合并、倍增、扫描线

    传送门 朴素想法:对\(M\)个匹配串\(T_1,...,T_M\)建立广义SAM,对于每一次询问,找到这个SAM上\(S[pl...pr]\)对应的状态,然后计算出对于每一个\(i \in [l,r ...

  9. Luogu4022 CTSC2012 熟悉的文章 广义SAM、二分答案、单调队列

    传送门 先将所有模板串扔进广义SAM.发现作文的\(L0\)具有单调性,即\(L0\)更小不会影响答案,所以二分答案. 假设当前二分的值为\(mid\),将当前的作文放到广义SAM上匹配. 设对于第\ ...

随机推荐

  1. maven安装与在eclipse中配置

    需要准备 eclipse maven压缩包 : http://maven.apache.org/download.cgi 1 解压maven压缩包 2 在系统变量中新建变量MAVEN_HOME,值为 ...

  2. 史上最详细的C语言和Python的插入排序算法

    史上最详细的C语言和Python的插入排序算法插入排序原理:所谓插入排序,就像我们在打牌(斗地主)时,整理我们自己手中自己的牌一样,就像是2,1,3,9,J,K,5,4,这四张牌.我们要把它其中的几张 ...

  3. 201871010114-李岩松《面向对象程序设计(java)》第七周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  4. 手把手教你用netty撸一个ZkClient

    原文地址: https://juejin.im/post/5dd296c0e51d4508182449a6 前言 有这个想法的缘由是前一阵子突发奇想, 想尝试能不能直接利用js连接到zookeeper ...

  5. 实现两个数字的交换(C语言)

    int num1=10; int num2=20; //1.简单的数学方法实现数字交换 num1=num1+num2;//num1=30 num2=num1-num2;//num2=10 num1=n ...

  6. Mysql主从同步的实现原理与配置实战

    1.什么是mysql主从同步? 当master(主)库的数据发生变化的时候,变化会实时的同步到slave(从)库. 2.主从同步有什么好处? 水平扩展数据库的负载能力. 容错,高可用.Failover ...

  7. suseoj 1208: 排列问题 (STL, next_permutation(A.begin(), A.end()))

    1208: 排列问题 时间限制: 1 Sec  内存限制: 128 MB提交: 2  解决: 2[提交][状态][讨论版][命题人:liyuansong] 题目描述 全排列的生成就是对于给定的字符集或 ...

  8. 【SpringBoot | Redis】SpringBoot整合Redis

    SpringBoot整合Redis 1. pom.xml中引入Redis相关包 请注意,这里我们排除了lettuce驱动,采用了jedis驱动 <!-- redis的依赖 --> < ...

  9. 使用sklearn和caffe进行逻辑回归 | Brewing Logistic Regression then Going Deeper

    原文首发于个人博客https://kezunlin.me/post/c50b0018/,欢迎阅读! Brewing Logistic Regression then Going Deeper. Bre ...

  10. 达梦"记录超长"警告

    出现"记录超长"背景介绍: 导入数据库时,出现数据库记录超长警告,导致数据无法正常导入! 1.重新建库,把页大小改大 这种方式是在建立数据库实例的时候进行的 修改[页大小] 2.把 ...