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

题解:建一个广义sam,对于每次插入的点,我们需要更新val一遍,向suffix link也就是fa数组往前跳即可,需要打个标记,对于同一个串插入时,每个点只更新一次

数组开小了wa到死= =

//#pragma GCC optimize(2)
//#pragma GCC optimize(3)
//#pragma GCC optimize(4)
//#pragma GCC optimize("unroll-loops")
//#pragma comment(linker, "/stack:200000000")
//#pragma GCC optimize("Ofast,no-stack-protector")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include<bits/stdc++.h>
#define fi first
#define se second
#define db double
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define vi vector<int>
#define mod 1000000007
#define ld long double
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
//#define cd complex<double>
#define ull unsigned long long
#define base 1000000000000000000
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
#define fin freopen("i.in","r",stdin)
#define fout freopen("i.ans","w",stdout)
#define fio ios::sync_with_stdio(false);cin.tie(0)
template<typename T>
inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
template<typename T>
inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;} using namespace std; const double eps=1e-8;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int N=1000000+10,maxn=1000000+10,inf=0x3f3f3f3f; char s[N];
vi v[10000+10];
ll ans[N<<1];
struct SAM{
int last,cnt;
int ch[N<<1][26],fa[N<<1],l[N<<1],co[N];
ll val[N<<1];
void init()
{
cnt=1;
}
void ins(int x)
{
int p=last,np=++cnt;last=np;l[np]=l[p]+1;
val[np]=1;
for(;p&&!ch[p][x];p=fa[p])ch[p][x]=np;
if(!p)fa[np]=1;
else
{
int q=ch[p][x];
if(l[q]==l[p]+1)fa[np]=q;
else
{
int nq=++cnt;l[nq]=l[p]+1;
val[nq]=1;
memcpy(ch[nq],ch[q],sizeof ch[q]);
fa[nq]=fa[q];fa[q]=fa[np]=nq;
for(;ch[p][x]==q;p=fa[p])ch[p][x]=nq;
}
}
}
void build(int id)
{
last=1;
int len=v[id].size();
for(int i=0;i<len;i++)ins(v[id][i]);
}
void update(int id,ll vv)
{
int len=v[id].size(),now=1;
for(int i=0;i<len;i++)
{
now=ch[now][v[id][i]];
for(int j=now;j&&co[j]<id;j=fa[j])
{
co[j]=id;
val[j]=val[j]*vv%mod;
}
}
}
void cal()
{
for(int i=1;i<=cnt;i++)
{
ans[l[i]+1]=((ans[l[i]+1]-val[i])%mod+mod)%mod;
ans[l[fa[i]]+1]=(ans[l[fa[i]]+1]+val[i])%mod;
}
for(int i=1;i<N*2;i++)ans[i]=(ans[i]+ans[i-1])%mod;
for(int i=1;i<N*2;i++)ans[i]=(ans[i]+ans[i-1])%mod;
}
}sam;
ll f[maxn];
int main()
{
fin;fout;
int n;
scanf("%d",&n);
sam.init();
for(int i=1;i<=n;i++)
{
scanf("%s",s);
int len=strlen(s);
for(int j=0;j<len;j++)v[i].pb(s[j]-'a');
sam.build(i);
}
for(int i=1;i<=n;i++)
{
int x;scanf("%d",&x);
sam.update(i,x);
}
sam.cal();
f[0]=0;
for(int i=1;i<maxn;i++)f[i]=(f[i-1]*26%mod+26)%mod;
for(int i=1;i<maxn;i++)f[i]=qp(f[i],mod-2);
int q;scanf("%d",&q);
while(q--)
{
int m;scanf("%d",&m);
printf("%lld\n",ans[m]*f[m]%mod);
}
return 0;
}
/********************
2
zybnb
ybyb
3 5
4
1
2
3
4
********************/

hdu6405Make ZYB Happy 广义sam的更多相关文章

  1. HDU 6405 Make ZYB Happy(广义SAM)

    It's known to all that ZYB is godlike, so obviously he has a large number of titles, such as jskingj ...

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

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

  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. [转载]C#操作符??和?:

    先看如下代码: string strParam = Request.Params["param"]; if ( strParam== null ) {     strParam= ...

  2. CSS3实现8种Loading效果【二】

    CSS3实现8种Loading效果[二]   今晚吃完饭回宿舍又捣鼓了另外几种Loading效果,老规矩,直接“上菜“…… 注:gif图片动画有些卡顿,非实际效果! 第一种效果: 代码如下: < ...

  3. (一)MySQL登录与退出

    mysql登陆: win+r输入cmd按enter进入命令行界面: > mysql -uroot -p -P3306 -h127.0.0.1 > 输入密码后按回车 mysql退出: mys ...

  4. Linux 系统版本信息

    1.# uname -a   (Linux查看版本当前操作系统内核信息) 2.# cat /proc/version (Linux查看当前操作系统版本信息) 3.# cat /etc/issue  或 ...

  5. 05: MySQL高级查询

    MySQL其他篇 目录: 参考网站 1.1 GROUP BY分组使用 1.2 mysql中NOW(),CURDATE(),CURTIME()的使用 1.3 DATEDIFF() 函数 1.4 DATE ...

  6. csharp编写界面,opencv编写类库,解决 Pinvoke过程中的参数传递和平台调用问题

        使用csharp 编写winform程序,不仅速度快,而且容易界面美化并找到其他类库的支持:而使用 opencv编写图形图像处理程序,是目前比较流行,而且高效的一种方法.如果需要将两者结合,需 ...

  7. linux内核分析 1、2章读书笔记

    一.linux历史 20世纪60年代,MIT开发分时操作系统(Compatible TIme-Sharing System),支持30台终端访问主机: 1965年,Bell实验室.MIT.GE(通用电 ...

  8. 命令模式(head first 设计模式5)

    一.命令模式定义 命令大家都不会陌生,那么在开始命令模式之前,可以想象一下生活中的命令模式的特点: 如老板命令你完成一个OA项目是一个命令,接着看看其特点: 1.在上面的命令中,命令的执行者肯定是聪明 ...

  9. SVN基本命令总结

    1.svn add [path] 预定添加文件或者目录到版本库,这些add的文件会在下一次提交文件时同步到版本服务器. 2.svn commit [path] 提交文件到版本服务器. 3.svn co ...

  10. Python中通过csv的writerow输出的内容有多余的空行

    第一种方法 如下生成的csv文件会有多个空行 import csv #python2可以用file替代open with open("test.csv","w" ...