hdu 2433 考研路茫茫——单词情结 ac自动机+矩阵快速幂+dp
2016-10-06 12:34
489 查看
题意:
和poj2778很像,这个是求包含病毒串的有多少个。那么我们求出不包含的在用总数相减就可以得到答案。
///对于2^64取mod 可以直接用unsigned long long
ACcode:
#include <bits/stdc++.h>
#define maxn 160
#define ll unsigned long long
using namespace std;
int m;
ll N;
char str[33];
struct Aho{
struct state{
int next[26];
int fail,cnt;
}s[maxn];
int size;
queue<int>q;
void init(){
size=1;
for(int i=0;i<maxn;++i){
memset(s[i].next,-1,sizeof(s[i].next));
s[i].fail=s[i].cnt=0;
}
while(q.size())q.pop();
}
void insert(char *str){
int n=strlen(str);
int now=0;
for(int i=0;i<n;++i){
int id=str[i]-'a';
if(s[now].next[id]==-1)
s[now].next[id]=size++;
now=s[now].next[id];
}
s[now].cnt=1;
}
struct Matrix{
ll mat[maxn][maxn];
};
Matrix mul(Matrix a,Matrix b){
Matrix ret;
memset(ret.mat,0,sizeof(ret.mat));
for(int i=0;i<size;++i)
for(int j=0;j<size;++j)
for(int k=0;k<size;++k)
ret.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
return ret;
}
Matrix pow(Matrix a,ll k){
Matrix ret;
memset(ret.mat,0,sizeof(ret.mat));
for(int i=0;i<size;++i)ret.mat[i][i]=1;
while(k){
if(k&1)ret=mul(ret,a);
a=mul(a,a);
k>>=1;
}
return ret;
}
void build(){
s[0].fail=0;
for(int i=0;i<26;++i)
if(s[0].next[i]==-1)
s[0].next[i]=0;
else {
s[s[0].next[i]].fail=0;
q.push(s[0].next[i]);
}
while(q.size()){
int u=q.front();q.pop();
if(s[s[u].fail].cnt)s[u].cnt=1;
for(int i=0;i<26;++i){
if(s[u].next[i]==-1)
s[u].next[i]=s[s[u].fail].next[i];
else {
s[s[u].next[i]].fail=s[s[u].fail].next[i];
q.push(s[u].next[i]);
}
}
}
Matrix tmp;
memset(tmp.mat,0,sizeof(tmp.mat));
for(int i=0;i<size;++i){
if(s[i].cnt)continue;
for(int j=0;j<26;++j)
if(!s[s[i].next[j]].cnt)
tmp.mat[i][s[i].next[j]]++;
}
for(int i=0;i<=size;++i)
tmp.mat[i][size]=1;
size++;
tmp=pow(tmp,N);
ll ans=0;
for(int i=0;i<size;++i)
ans=(ans+tmp.mat[0][i]);
Matrix temp;
memset(temp.mat,0,sizeof(temp.mat));
temp.mat[0][0]=26;
temp.mat[1][0]=temp.mat[1][1]=1;
temp=pow(temp,N);
ll res=0;
for(int i=0;i<size;++i)res=(res+temp.mat[i][0]);
cout<<res-ans<<'\12';
}
}aho;
int main(){
while(cin>>m>>N){
aho.init();
for(int i=0;i<m;++i){
scanf("%s",str);
aho.insert(str);
}
aho.build();
}
return 0;
}
和poj2778很像,这个是求包含病毒串的有多少个。那么我们求出不包含的在用总数相减就可以得到答案。
///对于2^64取mod 可以直接用unsigned long long
ACcode:
#include <bits/stdc++.h>
#define maxn 160
#define ll unsigned long long
using namespace std;
int m;
ll N;
char str[33];
struct Aho{
struct state{
int next[26];
int fail,cnt;
}s[maxn];
int size;
queue<int>q;
void init(){
size=1;
for(int i=0;i<maxn;++i){
memset(s[i].next,-1,sizeof(s[i].next));
s[i].fail=s[i].cnt=0;
}
while(q.size())q.pop();
}
void insert(char *str){
int n=strlen(str);
int now=0;
for(int i=0;i<n;++i){
int id=str[i]-'a';
if(s[now].next[id]==-1)
s[now].next[id]=size++;
now=s[now].next[id];
}
s[now].cnt=1;
}
struct Matrix{
ll mat[maxn][maxn];
};
Matrix mul(Matrix a,Matrix b){
Matrix ret;
memset(ret.mat,0,sizeof(ret.mat));
for(int i=0;i<size;++i)
for(int j=0;j<size;++j)
for(int k=0;k<size;++k)
ret.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
return ret;
}
Matrix pow(Matrix a,ll k){
Matrix ret;
memset(ret.mat,0,sizeof(ret.mat));
for(int i=0;i<size;++i)ret.mat[i][i]=1;
while(k){
if(k&1)ret=mul(ret,a);
a=mul(a,a);
k>>=1;
}
return ret;
}
void build(){
s[0].fail=0;
for(int i=0;i<26;++i)
if(s[0].next[i]==-1)
s[0].next[i]=0;
else {
s[s[0].next[i]].fail=0;
q.push(s[0].next[i]);
}
while(q.size()){
int u=q.front();q.pop();
if(s[s[u].fail].cnt)s[u].cnt=1;
for(int i=0;i<26;++i){
if(s[u].next[i]==-1)
s[u].next[i]=s[s[u].fail].next[i];
else {
s[s[u].next[i]].fail=s[s[u].fail].next[i];
q.push(s[u].next[i]);
}
}
}
Matrix tmp;
memset(tmp.mat,0,sizeof(tmp.mat));
for(int i=0;i<size;++i){
if(s[i].cnt)continue;
for(int j=0;j<26;++j)
if(!s[s[i].next[j]].cnt)
tmp.mat[i][s[i].next[j]]++;
}
for(int i=0;i<=size;++i)
tmp.mat[i][size]=1;
size++;
tmp=pow(tmp,N);
ll ans=0;
for(int i=0;i<size;++i)
ans=(ans+tmp.mat[0][i]);
Matrix temp;
memset(temp.mat,0,sizeof(temp.mat));
temp.mat[0][0]=26;
temp.mat[1][0]=temp.mat[1][1]=1;
temp=pow(temp,N);
ll res=0;
for(int i=0;i<size;++i)res=(res+temp.mat[i][0]);
cout<<res-ans<<'\12';
}
}aho;
int main(){
while(cin>>m>>N){
aho.init();
for(int i=0;i<m;++i){
scanf("%s",str);
aho.insert(str);
}
aho.build();
}
return 0;
}
相关文章推荐
- hdu_2243 _考研路茫茫――单词情结 (AC自动机+矩阵快速幂+...)
- hdu 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
- HDU 2243 考研路茫茫——单词情结 (AC自动机+矩阵快速幂求和)
- HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
- HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
- HDU 2243 考研路茫茫——单词情结(自动机DP+矩阵)
- HDU 2243 考研路茫茫——单词情结
- HDU2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
- Hdu 2243 考研路茫茫——单词情结 (AC自动机+矩阵)
- hdu 2243 考研路茫茫——单词情结
- HDU 2243 考研路茫茫——单词情结
- poj -- 2778 DNA Sequence && hdu -- 2243 考研路茫茫——单词情结(AC自动机 + 矩阵)
- HDU 2243 考研路茫茫——单词情结(AC自动机+矩阵幂)
- HDU 2243 考研路茫茫――单词情结 (AC自动机 + 矩阵快速幂)
- 【HDU】 2243 考研路茫茫——单词情结 AC自动机+矩阵加速
- hdu 2243考研路茫茫——单词情结—解题报告
- hdu 2243 考研路茫茫——单词情结
- hdu2243 考研路茫茫——单词情结(AC自动机+矩阵快速幂)
- hdu 2243 考研路茫茫——单词情结(AC自动+矩阵)
- HDU 2243 考研路茫茫——单词情结(自动机)