后缀自动机求不同的串,然后DP.....
K-hash
Time Limit: 2 Seconds Memory Limit: 131072 KB
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; }
版权声明:来自: 码代码的猿猿的AC之路 http://blog.csdn.net/ck_boss