제목 링크: Censored!
해결: AC 로봇 + 고정밀 + 단순 DP.
문자가 128을 초과할 수 있습니다. 맵으로 비추면 됩니다.
중간의 수가 너무 커서 높은 정밀도를 얻을 수 있다.
매트릭스 쾌속 멱을 사용하면 시간이 초과됩니다. 간단한 DP로 시간 문제를 해결할 수 있습니다.
AC 코드:
#include
#include
#include
#include
#include
#include
using namespace std;
mapmp;
int N,M,P;
struct Matrix
{
int mat[110][110];
int n;
Matrix(){}
Matrix(int _n)
{
n=_n;
for(int i = 0;i < n;i++)
for(int j = 0;j < n;j++)
mat[i][j] = 0;
}
};
struct Trie
{
int next[110][256],fail[110];
bool end[110];
int L,root;
int newnode()
{
for(int i = 0;i < 256;i++)
next[L][i] = -1;
end[L++] = false;
return L-1;
}
void init()
{
L = 0;
root = newnode();
}
void insert(char buf[])
{
int len = strlen(buf);
int now = root;
for(int i = 0;i < len;i++)
{
if(next[now][mp[buf[i]]] == -1)
next[now][mp[buf[i]]] = newnode();
now = next[now][mp[buf[i]]];
}
end[now] = true;
}
void build()
{
queueQ;
fail[root] = root;
for(int i = 0;i < 256;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();
if(end[fail[now]]==true)end[now]=true;
for(int i = 0;i < 256;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]);
}
}
}
Matrix getMatrix()
{
Matrix res = Matrix(L);
for(int i = 0;i < L;i++)
for(int j = 0;j < N;j++)
if(end[next[i][j]]==false)
res.mat[i][next[i][j]]++;
return res;
}
void debug()
{
for(int i = 0;i < L;i++)
{
printf("id = %3d,fail = %3d,end = %3d,chi = [",i,fail[i],end[i]);
for(int j = 0;j < 26;j++)
printf("%2d",next[i][j]);
printf("] ");
}
}
};
/*
* ,
*/
struct BigInt
{
const static int mod = 10000;
const static int DLEN = 4;
int a[600],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(" ");
}
};
char buf[1010];
BigInt dp[2][110];
Trie ac;
int main()
{
// freopen("in.txt","r",stdin);
while(scanf("%d%d%d",&N,&M,&P)==3)
{
gets(buf);
gets(buf);
mp.clear();
int len = strlen(buf);
for(int i = 0;i < len;i++)
mp[buf[i]]=i;
ac.init();
for(int i = 0;i < P;i++)
{
gets(buf);
ac.insert(buf);
}
ac.build();
Matrix a= ac.getMatrix();
int now = 0;
dp[now][0] = 1;
for(int i = 1;i < a.n;i++)
dp[now][i] = 0;
for(int i = 0;i < M;i++)
{
now^=1;
for(int j = 0;j < a.n;j++)
dp[now][j] = 0;
for(int j = 0;j < a.n;j++)
for(int k = 0;k < a.n;k++)
if(a.mat[j][k] > 0)
dp[now][k] = dp[now][k]+dp[now^1][j]*a.mat[j][k];
}
BigInt ans = 0;
for(int i = 0;i < a.n;i++)
ans = ans + dp[now][i];
ans.output();
}
return 0;
}
PS: 코드 스타일은 bin 신에게서 온 것입니다.
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
비슷한 이름의 Attribute를 많이 만들어 삭제하는 Houdini
사용 소프트웨어는 Houdini16.5입니다
배열에서는 애트리뷰트의 보간이 잘 동작하지 않는 것과 AttributeCreateSOP 노드에서 Size가 4를 넘는 애트리뷰트를 작성해도 값이 조작할 수 없어 의미가 없...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.