2017.8.14 文本生成器 失败总结
2017-08-14 19:24
148 查看
以后凡是在一个中出现>=1次的题就直接转0次用容斥好了、
然后剩下的就是怎么找一个单词也不出现的文本的个数了
显然,这种计数类问题需要用dp ,而且我们需要知道所有单词会为我们添加字母造成影响,所以需要用ac自动机,跳过所有标记的单词
以前是写的指针ac自动机,但它不好写而且巨慢、 所以换了数组
要注意用0表示null 1表示root 为了方便,我们将0的所有下一个赋为root 同时这个失配指针是指向最近的和自己相同的字母 root可表示所有字母..
而且失配是单词这个点也不能取,,因为
然后sp数组开小了溢出导致f数组储存信息错误、、查了1.5h才查出来
码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
queue<int>q;
int sz=1,ans1,ans2,n,m,i,j,sp[7000],ch[7000][27],dc[7000],f[105][7000];
char str[105];
#define P 10007
void ins()
{
int l=strlen(str),i,o=1;
for(i=0;i<l;i++)
{
int zm=str[i]-'A'+1;
if(ch[o][zm])o=ch[o][zm];
else o=ch[o][zm]=++sz;
}
dc[o]=1;
}
void shipei()
{
int i;sp[1]=0;
q.push(1);
while(!q.empty())
{
int st=q.front();
q.pop();
for(i=1;i<=26;i++)
{
if(ch[st][i]==0)continue;
int k=sp[st];
while(!ch[k][i])
k=sp[k];
sp[ch[st][i]]=ch[k][i];
if(dc[ch[k][i]])dc[ch[st][i]]=1;
q.push(ch[st][i]);
}
}
}
void dp(int x)
{
int i,j;
for(i=1;i<=sz;i++)
{
if(dc[i]||!f[x-1][i])continue;
for(j=1;j<=26;j++)
{
int k=i;
while(!ch[k][j])k=sp[k];
f[x][ch[k][j]]= (f[x][ch[k][j]] +f[x-1][i] )%P;//if(x<2)cout<<f[x][ch[k][j]]<<" ";
}
}
}
int main()
{
ans2=1;
scanf("%d%d",&n,&m) ;
for(i=1;i<=26;i++)ch[0][i]=1;
f[0][1]=1;
for(i=1;i<=n;i++)
{
scanf("%s",str);
ins();
}
shipei();
for(i=1;i<=m;i++)dp(i);
for(i=1;i<=m;i++)ans2=(ans2*26)%P;
for(i=1;i<=sz;i++)if(!dc[i])ans1=(ans1+f[m][i])%P;
printf("%d",(ans2-ans1+P)%P);
}
然后剩下的就是怎么找一个单词也不出现的文本的个数了
显然,这种计数类问题需要用dp ,而且我们需要知道所有单词会为我们添加字母造成影响,所以需要用ac自动机,跳过所有标记的单词
以前是写的指针ac自动机,但它不好写而且巨慢、 所以换了数组
要注意用0表示null 1表示root 为了方便,我们将0的所有下一个赋为root 同时这个失配指针是指向最近的和自己相同的字母 root可表示所有字母..
而且失配是单词这个点也不能取,,因为
然后sp数组开小了溢出导致f数组储存信息错误、、查了1.5h才查出来
码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
queue<int>q;
int sz=1,ans1,ans2,n,m,i,j,sp[7000],ch[7000][27],dc[7000],f[105][7000];
char str[105];
#define P 10007
void ins()
{
int l=strlen(str),i,o=1;
for(i=0;i<l;i++)
{
int zm=str[i]-'A'+1;
if(ch[o][zm])o=ch[o][zm];
else o=ch[o][zm]=++sz;
}
dc[o]=1;
}
void shipei()
{
int i;sp[1]=0;
q.push(1);
while(!q.empty())
{
int st=q.front();
q.pop();
for(i=1;i<=26;i++)
{
if(ch[st][i]==0)continue;
int k=sp[st];
while(!ch[k][i])
k=sp[k];
sp[ch[st][i]]=ch[k][i];
if(dc[ch[k][i]])dc[ch[st][i]]=1;
q.push(ch[st][i]);
}
}
}
void dp(int x)
{
int i,j;
for(i=1;i<=sz;i++)
{
if(dc[i]||!f[x-1][i])continue;
for(j=1;j<=26;j++)
{
int k=i;
while(!ch[k][j])k=sp[k];
f[x][ch[k][j]]= (f[x][ch[k][j]] +f[x-1][i] )%P;//if(x<2)cout<<f[x][ch[k][j]]<<" ";
}
}
}
int main()
{
ans2=1;
scanf("%d%d",&n,&m) ;
for(i=1;i<=26;i++)ch[0][i]=1;
f[0][1]=1;
for(i=1;i<=n;i++)
{
scanf("%s",str);
ins();
}
shipei();
for(i=1;i<=m;i++)dp(i);
for(i=1;i<=m;i++)ans2=(ans2*26)%P;
for(i=1;i<=sz;i++)if(!dc[i])ans1=(ans1+f[m][i])%P;
printf("%d",(ans2-ans1+P)%P);
}
相关文章推荐
- 2017.8.14 分手是祝愿 失败总结
- 2017.9.2 王室联邦 失败总结
- (大总结)从寻找fragment静态导入activity总是失败的解决方法中了解android应用的系统启动过程
- 生鲜电商“优菜网”创业失败总结
- linux下免密认证登录失败原因总结
- rvds 2.2 破解失败 经验总结
- 智能一代云平台(十一):Eclipse启动项目报启动上下文失败问题解决方案总结
- LINUX总结第3篇:执行service mysql start失败解决方法
- 2017.9.11 聪明的燕姿 失败总结
- playcafe创始人:总结自己创业失败的10个教训
- 2012年项目失败原因总结
- hive启动失败的小问题总结以及hive
- 物联网碰壁后,这位创业者总结失败五大原因
- android.cts.jank.ui.CtsDeviceJankUi--testScrolling失败原因总结和debug方法介绍
- MySQL数据库建立外键失败的原因总结
- 2017.7.31 征途 失败总结
- 【错误总结之(二)】LINK : fatal error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- 百度校招失败经历总结(应聘职位:产品运营师-北京)
- 失败中总结经验