hihocoder1457
http://hihocoder.com/problemset/problem/1457
找不重复子串的和
topo序搞一搞,用父亲更新儿子节点的val,记得乘上节点数
//#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")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod (1000000007)
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pii pair<int,int>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; inline void sub(ll &x){if(x>=mod)x-=mod;}
char s[N];
int c[N],a[N];
ll val[N],sum[N];
struct SAM{
int last,cnt;
int ch[N<<][],fa[N<<],l[N<<];
int mx[N<<],tmp[N<<];
void ins(int c)
{
int p=last,np=++cnt;last=np;l[np]=l[p]+;
for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;
if(!p)fa[np]=;
else
{
int q=ch[p][c];
if(l[p]+==l[q])fa[np]=q;
else
{
int nq=++cnt;l[nq]=l[p]+;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];fa[q]=fa[np]=nq;
sum[nq]=1ll*c;
for(;ch[p][c]==q;p=fa[p])ch[p][c]=nq;
}
}
sum[np]=1ll*c;
}
SAM()
{
cnt=;
}
void build(){
int len=strlen(s+);
last=;
for(int i=;i<=len;i++)ins(s[i]-'');
// topo();
// for(int i=1;i<=cnt;i++)mx[i]=l[i],tmp[i]=0;
}
void topo(){
for(int i=;i<=cnt;i++)c[l[i]]++;
for(int i=;i<=cnt;i++)c[i]+=c[i-];
for(int i=;i<=cnt;i++)a[c[l[i]]--]=i;
}
void debug()
{
puts("");
for(int i=;i<=cnt;i++)
{
printf("%d ",i);
for(int j=;j<;j++)
printf("%d ",ch[i][j]);
printf("%d %d %lld %lld\n",fa[i],l[i],val[i],sum[i]);
}
}
void faupdate()
{
for(int i=cnt;i;i--)
tmp[fa[a[i]]]=max(tmp[fa[a[i]]],tmp[a[i]]);
}
void maupdate()
{
for(int i=;i<=cnt;i++)
mx[i]=min(mx[i],tmp[i]),tmp[i]=;
}
void match()
{
int len=strlen(s+),now=,res=;
for(int i=;i<=len;i++)
{
if(ch[now][s[i]-'a'])
{
now=ch[now][s[i]-'a'];
res++;
}
else
{
while(now&&!ch[now][s[i]-'a'])now=fa[now];
if(!now)now=,res=;
else
{
res=l[now]+;
now=ch[now][s[i]-'a'];
}
}
tmp[now]=max(tmp[now],res);
}
faupdate();
maupdate();
}
int maxlen()
{
int ans=;
for(int i=;i<=cnt;i++)ans=max(ans,mx[i]);
return ans;
}
void cal()
{
topo();
for(int i=;i<=cnt;i++)
{
int p=a[i];
val[p] = val[p] + 1ll*sum[p] * (l[p] - l[fa[p]])%mod;
sub(val[p]);
for(int j=;j<;j++)
{
if(ch[p][j])
{
val[ch[p][j]]=val[ch[p][j]]+val[p]*10ll%mod;
sub(val[ch[p][j]]);
}
}
// cout << val[p] << endl;
}
// debug();
ll ans=;
for(int i=cnt;i;i--)
{
ans=ans+val[i];
sub(ans);
}
printf("%lld\n",ans);
}
}sam;
int main()
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%s",s+);
sam.build();
}
sam.cal();
return ;
}
/********************
1
101
********************/
版本1
//#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")
//#pragma GCC optimize("unroll-loops")
#include<bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define pi acos(-1.0)
#define ll long long
#define mod (1000000007)
#define C 0.5772156649
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define pil pair<int,ll>
#define pii pair<int,int>
#define ull unsigned long long
#define base 1000000000000000000
#define fio ios::sync_with_stdio(false);cin.tie(0) using namespace std; const double g=10.0,eps=1e-;
const int N=+,maxn=+,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f; inline void sub(ll &x){if(x>=mod)x-=mod;}
char s[N];
int c[N],a[N];
ll val[N],sum[N],sz[N];
struct SAM{
int last,cnt;
int ch[N<<][],fa[N<<],l[N<<];
int mx[N<<],tmp[N<<];
void ins(int c)
{
int p=last,np=++cnt;last=np;l[np]=l[p]+;
for(;p&&!ch[p][c];p=fa[p])ch[p][c]=np;
if(!p)fa[np]=;
else
{
int q=ch[p][c];
if(l[p]+==l[q])fa[np]=q;
else
{
int nq=++cnt;l[nq]=l[p]+;
memcpy(ch[nq],ch[q],sizeof(ch[q]));
fa[nq]=fa[q];fa[q]=fa[np]=nq;
for(;ch[p][c]==q;p=fa[p])ch[p][c]=nq;
}
}
sum[np]=1ll*c;
}
SAM()
{
cnt=;
}
void build(){
int len=strlen(s+);
last=;
for(int i=;i<=len;i++)ins(s[i]-'');
// topo();
// for(int i=1;i<=cnt;i++)mx[i]=l[i],tmp[i]=0;
}
void topo(){
for(int i=;i<=cnt;i++)c[l[i]]++;
for(int i=;i<=cnt;i++)c[i]+=c[i-];
for(int i=;i<=cnt;i++)a[c[l[i]]--]=i;
}
void debug()
{
puts("");
for(int i=;i<=cnt;i++)
{
printf("%d ",i);
for(int j=;j<;j++)
printf("%d ",ch[i][j]);
printf("%d %d %lld %lld\n",fa[i],l[i],val[i],sum[i]);
}
}
void faupdate()
{
for(int i=cnt;i;i--)
tmp[fa[a[i]]]=max(tmp[fa[a[i]]],tmp[a[i]]);
}
void maupdate()
{
for(int i=;i<=cnt;i++)
mx[i]=min(mx[i],tmp[i]),tmp[i]=;
}
void match()
{
int len=strlen(s+),now=,res=;
for(int i=;i<=len;i++)
{
if(ch[now][s[i]-'a'])
{
now=ch[now][s[i]-'a'];
res++;
}
else
{
while(now&&!ch[now][s[i]-'a'])now=fa[now];
if(!now)now=,res=;
else
{
res=l[now]+;
now=ch[now][s[i]-'a'];
}
}
tmp[now]=max(tmp[now],res);
}
faupdate();
maupdate();
}
int maxlen()
{
int ans=;
for(int i=;i<=cnt;i++)ans=max(ans,mx[i]);
return ans;
}
void cal()
{
topo();
sz[]=;
for(int i=;i<=cnt;i++)
{
int p=a[i];
// val[p] = val[p] + 1ll*sum[p] * (l[p]-l[fa[p]])%mod;
// sub(val[p]);
for(int j=;j<;j++)
{
if(ch[p][j])
{
val[ch[p][j]]=val[ch[p][j]]+val[p]*10ll%mod+1ll*j*sz[p]%mod;
sub(val[ch[p][j]]);
sz[ch[p][j]]+=sz[p];
}
}
// cout << val[p] << endl;
}
// debug();
ll ans=;
for(int i=cnt;i;i--)
{
ans=ans+val[i];
sub(ans);
}
printf("%lld\n",ans);
}
}sam;
int main()
{
int n;
scanf("%d",&n);
for(int i=;i<=n;i++)
{
scanf("%s",s+);
sam.build();
// if(i!=n)sam.ins(10);
}
sam.cal();
return ;
}
/********************
1
987654321123456789
********************/
版本2
hihocoder1457的更多相关文章
- 【后缀自动机】【拓扑排序】【动态规划】hihocoder1457 后缀自动机四·重复旋律7
解题方法提示 小Hi:我们已经学习了后缀自动机,今天我们再来看这道有意思的题. 小Ho:好!这道题目让我们求的是若干的数字串所有不同子串的和. 小Hi:你能不能结合后缀自动机的性质来思考如何解决本题? ...
随机推荐
- Selenium 方法封装 一
Selenium 封装 Selenium 封装 WebDriver对页面的操作,需要找到一个WebElement,然后再对其进行操作,比较繁琐: WebElement element =driver. ...
- docker——端口映射与容器互联
在生产环境中,单个服务往往是独立的,但是服务与服务之间往往是相互依赖的,这样对于容器来说,容器之间就需要相互访问.除了网络访问之外,docker还提供了另外两种方式来满足服务的访问. 一:允许映射容器 ...
- Zen cart 根据数量打折插件
Quantity Discounts 可以根据顾客购买多少来打折,很不错. 假如顾客买了3个以上的产品,就给他10%折扣,设置如下: Turn On Quantity Discount 1. In t ...
- git 移除某个文件的版本管理
1:最简单的,在项目刚创建的时候,在根目录的.gitignore,加入该文件的相对路径 2:已经被纳入到了版本控制,使用在当前目录下,打开cmd窗口 输入rm命令,加上文件的绝对路径(相对路径没试过) ...
- C# WinForm 父窗体 子窗体 传值
C# WinForm 父窗体 子窗体 传值 本次示例效果如下:Form1为父窗体(包含textBox1.button1)Form2为子窗体(包含textBox2.button2) 父窗体给子窗体传值= ...
- 基于Python操作redis介绍
(注:本文部分内容摘自互联网,由于作者水平有限,不足之处,还望留言指正.) 毕业前的最后一个学期(2016.03),龙哥结婚了.可是总有些人喜欢嘲笑别人,调侃我.当时我就理直气壮的告诉他们,等龙哥孩子 ...
- ajax的认识
1. ajax是一种技术,无需刷新页面即可向服务器传输.读写数据. 2. ajax的参数说明: 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为 ...
- 20145303刘俊谦 《Java程序设计》第2周学习总结
20145303刘俊谦 <Java程序设计>第2周学习总结 教材学习内容总结 1.对于标识符的一些名称规范(觉得挺重要而且容易混淆!定义就不写了,列一些例子): 包名: xxxyyyzzz ...
- tiny4412的烧录工具minitool安装【学习笔记】
烧录了半天,在win10下一直就是烧录不进去,但是在Ubuntuh环境却可以,找了很久终于找到了,原来在win10安装minitool驱动的时候没有注意到报了错误,错误内容是驱动的数字签名问题,后来禁 ...
- 1970年1月1日(00:00:00 GMT)Unix 时间戳(Unix Timestamp)
转载自(http://jm.ncxyol.com/post-88.html) 今天在看Python API时,看到time模块: The epoch is the point where the ...