Time Limit: 5000MS | Memory Limit: 10000K | |
Total Submissions: 7469 | Accepted: 2023 |
Description
Input
Output
Sample Input
2 3 1 ab bb
Sample Output
5
题意:给定n个字符,p个禁止出现的序列,求长度为m的合法序列有多少个。
解题思路很简单,不过这个题计算结果不是取模,只能高精度,wa多次,tle,mle都出现了,过得比较艰难。
代码:
/* *********************************************** Author :xianxingwuguan Created Time :2014-2-5 11:29:37 File Name :3.cpp ************************************************ */ #pragma comment(linker, "/STACK:102400000,102400000") #include <stdio.h> #include <iostream> #include <algorithm> #include <sstream> #include <stdlib.h> #include <string.h> #include <limits.h> #include <string> #include <time.h> #include <math.h> #include <queue> #include <stack> #include <set> #include <map> using namespace std; #define INF 0x3f3f3f3f #define eps 1e-8 #define pi acos(-1.0) typedef long long ll; map<char,int> mp; int n; struct BigInt { const static int mod = 10000; const static int DLEN = 4; int a[110],len; BigInt() { memset(a,0,sizeof(a)); len = 1; } BigInt(int v) { memset(a,0,sizeof(a)); len = 0; do { a[len++] = v%mod; v /= mod; }while(v); } BigInt(const char s[]) { memset(a,0,sizeof(a)); int L = strlen(s); len = L/DLEN; if(L%DLEN)len++; int index = 0; for(int i = L-1;i >= 0;i -= DLEN) { int t = 0; int k = i - DLEN + 1; if(k < 0)k = 0; for(int j = k;j <= i;j++) t = t*10 + s[j] - ‘0‘; a[index++] = t; } } BigInt operator +(const BigInt &b)const { BigInt res; res.len = max(len,b.len); for(int i = 0;i <= res.len;i++) res.a[i] = 0; for(int i = 0;i < res.len;i++) { res.a[i] += ((i < len)?a[i]:0)+((i < b.len)?b.a[i]:0); res.a[i+1] += res.a[i]/mod; res.a[i] %= mod; } if(res.a[res.len] > 0)res.len++; return res; } BigInt operator *(const BigInt &b)const { BigInt res; for(int i = 0; i < len;i++) { int up = 0; for(int j = 0;j < b.len;j++) { int temp = a[i]*b.a[j] + res.a[i+j] + up; res.a[i+j] = temp%mod; up = temp/mod; } if(up != 0) res.a[i + b.len] = up; } res.len = len + b.len; while(res.a[res.len - 1] == 0 &&res.len > 1)res.len--; return res; } void output() { printf("%d",a[len-1]); for(int i = len-2;i >=0 ;i--) printf("%04d",a[i]); printf("\n"); } }dp[110][110]; struct Trie{ int next[110][70],end[110],fail[110]; int root,L; int newnode(){ for(int i=0;i<n;i++) next[L][i]=-1; end[L++]=0; return L-1; } void init(){ L=0; root=newnode(); } void insert(char *str){ int len=strlen(str); int now=root; for(int i=0;i<len;i++){ int p=mp[str[i]]; if(next[now][p]==-1) next[now][p]=newnode(); now=next[now][p]; } end[now]|=1; } void build(){ queue<int> q; fail[root]=root; for(int i=0;i<n;i++) if(next[root][i]==-1) next[root][i]=root; else { fail[next[root][i]]=root; q.push(next[root][i]); } while(!q.empty()){ int now=q.front(); q.pop(); end[now]|=end[fail[now]]; for(int i=0;i<n;i++) if(next[now][i]==-1) next[now][i]=next[fail[now]][i]; else { fail[next[now][i]]=next[fail[now]][i]; q.push(next[now][i]); } } } void solve(int m){ for(int i=0;i<=m;i++) for(int j=0;j<=L;j++) dp[i][j]=BigInt(0); dp[0][0]=BigInt(1); for(int i=0;i<m;i++) for(int j=0;j<L;j++){ for(int k=0;k<n;k++){ int p=next[j][k]; if(end[p])continue; dp[i+1][p]=dp[i][j]+dp[i+1][p]; } } BigInt ans=BigInt(0); for(int i=0;i<L;i++) ans=ans+dp[m][i]; ans.output(); } }ac; char str[10000]; int main() { //freopen("data.in","r",stdin); //freopen("data.out","w",stdout); int i,j,k,m,p; while(~scanf("%d%d%d",&n,&m,&p)){ ac.init();mp.clear(); getchar(); gets(str); for(i=0;i<n;i++) mp[str[i]]=i; while(p--){ gets(str); ac.insert(str); } ac.build(); ac.solve(m); } return 0; }
原文:http://blog.csdn.net/xianxingwuguan1/article/details/18938841