后缀自动机求不同的串,然后DP.....
K-hash
K-hash is a simple string hash function. It encodes a string Sconsist of digit characters into a K-dimensional vector (h0, h1, h2,... , hK-1). If a nonnegative number xoccurs in S, then we call x is S-holded. And hi is the number of nonnegative numbers which are S-holded and congruent with i modulo K, for i from 0 to K-1.
For example, S is "22014" and K=3. There are 12 nonnegative numbers are "22014"-holded: 0, 1, 2, 4, 14, 20, 22, 201, 220, 2014, 2201 and 22014. And three of them, 0, 201 and 22014, are congruent with 0 modulo K, so h0=3. Similarly, h1=5 (1, 4, 22, 220 and 2014 are congruent with 1 modulo 3), h2=4(2, 14, 20 and 2201 are congruent with 2 modulo 3). So the 3-hash of "22014" is (3, 5, 4).
Please calculate the K-hash value of the given string S.
Input
There are multiple cases. Each case is a string S and a integer number K. (S is a string consist of '0', '1', '2', ... , '9' , 0< |S| ≤ 50000, 0< K≤ 32)
Output
For each case, print K numbers (h0, h1, h2,... , hK-1 ) in one line.
Sample Input
123456789 10 10203040506007 13 12345678987654321 2 112123123412345123456123456712345678123456789 17 3333333333333333333333333333 11
Sample Output
0 1 2 3 4 5 6 7 8 9 3 5 5 4 3 2 8 3 5 4 2 8 4 68 77 57 58 59 53 49 57 60 55 51 45 59 55 53 49 56 42 57 14 0 0 14 0 0 0 0 0 0 0
Author: ZHOU, Yuchen
Source: ZOJ Monthly, July 2023
/* ***********************************************
Author :CKboss
Created Time :2015年08月25日 星期二 10时22分16秒
File Name :ZOJ3891_2.cpp
************************************************ */
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>
using namespace std;
const int maxn=100500;
struct SAM_Node
{
SAM_Node *fa,*next[10];
int len,id,pos;
SAM_Node(){}
SAM_Node(int _len)
{
fa=0; len=_len;
memset(next,0,sizeof(next));
}
};
SAM_Node SAM_node[maxn],*SAM_root,*SAM_last;
int SAM_size;
SAM_Node *newSAM_Node(int len)
{
SAM_node[SAM_size]=SAM_Node(len);
SAM_node[SAM_size].id=SAM_size;
return &SAM_node[SAM_size++];
}
SAM_Node *newSAM_Node(SAM_Node *p)
{
SAM_node[SAM_size]=*p;
SAM_node[SAM_size].id=SAM_size;
return &SAM_node[SAM_size++];
}
void SAM_init()
{
SAM_size=1;
SAM_root=SAM_last=newSAM_Node(0);
SAM_node[0].pos=0;
}
void SAM_add(int x,int len)
{
SAM_Node *p=SAM_last,*np=newSAM_Node(p->len+1);
np->pos=len; SAM_last=np;
for(;p&&!p->next[x];p=p->fa)
p->next[x]=np;
if(!p)
{
np->fa=SAM_root;
return ;
}
SAM_Node *q=p->next[x];
if(q->len==p->len+1)
{
np->fa=q;
return ;
}
SAM_Node *nq=newSAM_Node(q);
nq->len=p->len+1;
q->fa=nq; np->fa=nq;
for(;p&&p->next[x]==q;p=p->fa)
p->next[x]=nq;
}
void SAM_build(char *s)
{
SAM_init();
int len=strlen(s);
for(int i=0;i<len;i++)
SAM_add(s[i]-'0',i+1);
}
int du[maxn];
int ans[40];
int dp[maxn][40];
void solve(int K)
{
memset(du,0,sizeof(du));
for(int i=1;i<SAM_size;i++)
{
for(int j=0;j<10;j++)
{
SAM_Node* to=SAM_node[i].next[j];
if(to!=0) du[to->id]++;
}
}
queue<int> q;
for(int i=1;i<SAM_size;i++) if(du[i]==0) q.push(i);
memset(dp,0,sizeof(dp));
dp[1][0]=1;
while(!q.empty())
{
int u=q.front(); q.pop();
for(int i=0;i<10;i++)
{
SAM_Node* to=SAM_node[u].next[i];
if(to==0) continue;
else
{
int v=SAM_node[u].next[i]->id;
du[v]--;
if(du[v]==0) q.push(v);
if(u==1&&i==0) continue;
for(int j=0;j<K;j++)
{
dp[v][(j*10+i)%K]+=dp[u][j];
}
}
}
}
}
char str[maxn];
int k;
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
while(cin>>str>>k)
{
SAM_build(str);
solve(k);
memset(ans,0,sizeof(ans));
for(int i=2;i<SAM_size;i++)
for(int j=0;j<k;j++) ans[j]=ans[j]+dp[i][j];
for(int i=0,len=strlen(str);i<len;i++)
{
if(str[i]=='0') { ans[0]++; break; }
}
for(int i=0;i<k;i++)
printf("%d%c",ans[i],(i==k-1)?10:32);
}
return 0;
}