题意:给出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. Linux基础命令---bunzip2

    bunzip2 解压缩bzip2压缩过的文件. 此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedora. 1.语法       bunzip2  ...

  2. Socket和ServletSocket的交互

    ServerSocket(int port) 是服务端绑定port端口,调accept()监听等待客户端连接,它返回一个连接队列中的一个socket. Socket(InetAddress addre ...

  3. PHP实现多进程并行操作,可做守护进程(转,备用)

    <?php /** * 入口函数 * 将此文件保存为 ProcessOpera.php * 在terminal中运行 /usr/local/php/bin/php ProcessOpera.ph ...

  4. Android 拖动条 和 Handle

  5. QTQuick控件基础(1)

    一.Item QtQuick所有的可视项目都继承自Item,它定义了可视化项目所有通用特性(x\y\width\height\anchors等)具体包括 1.作为容器 2.不透明性 没有设置opaci ...

  6. 20145106《Java程序设计》第7周学习总结

    教材学习内容总结 使用Lambda的特性可以去除重复的信息,以取得语法的简洁,增加程序代码的表达性.Lambda表达式本身是中性的,不代表任何类型的实例,同样的Lambda表达式,可用来表示不同目标类 ...

  7. 20145313exp9

    问题回答 SQL注入攻击原理,如何防御 所谓SQL注入,就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令.具体来说,它是利用现有应用程序 ...

  8. 20145334赵文豪《网络对抗》-逆向及Bof基础实践

    本次实践的对象是一个名为pwn1的linux可执行文件. 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串. 该程序同时包含另一个代码片段,getShell,会返 ...

  9. ubuntu16.04下内核模块解析

    一.环境如下: 1.1内核版本: jello@jello:~$ uname -a Linux jello 4.4.0-89-generic #112-Ubuntu SMP Mon Jul 31 19: ...

  10. winform中splitter的用法

    1.将winform分为三列 整个窗体分成可以自动调节的三列的做法:1.往窗体上丢两个panel控件其中:panelLeft——设置Dock属性为“left”,并调节好其宽度panelRight——设 ...