ZOJ 3891 K-hash

K-hash

Time Limit: 2000ms

Memory Limit: 131072KB

This problem will be judged on ZJU. Original ID: 3891
64-bit integer IO format: %lld      Java class name: Main

K-hash is a simple string hash function. It encodes a string Sconsist of digit characters into a K-dimensional vector (h0h1h2,... , hK-1). If a nonnegative number x occurs 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 (h0h1h2,... , 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

Source

ZOJ Monthly, July 2023

Author

ZHOU, Yuchen

解题:在SAM上dp

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 351000;
 4 struct SAM {
 5     struct node {
 6         int son[26],f,len;
 7         void init() {
 8             f = -1;
 9             len = 0;
10             memset(son,-1,sizeof son);
11         }
12     } s[maxn<<1];
13     int tot,last;
14     void init() {
15         tot = last = 0;
16         s[tot++].init();
17     }
18     int newnode() {
19         s[tot].init();
20         return tot++;
21     }
22     void extend(int c){
23         int np = newnode(),p = last;
24         s[np].len = s[p].len + 1;
25         while(p != -1 && s[p].son[c] == -1){
26             s[p].son[c] = np;
27             p = s[p].f;
28         }
29         if(p == -1) s[np].f = 0;
30         else{
31             int q = s[p].son[c];
32             if(s[p].len + 1 == s[q].len) s[np].f = q;
33             else{
34                 int nq = newnode();
35                 s[nq] = s[q];
36                 s[nq].len = s[p].len + 1;
37                 s[q].f = s[np].f = nq;
38                 while(p != -1 && s[p].son[c] == q){
39                     s[p].son[c] = nq;
40                     p = s[p].f;
41                 }
42             }
43         }
44         last = np;
45     }
46 } sam;
47 queue<int>q;
48 int du[maxn],dp[maxn][32],ans[maxn],k;
49 char str[maxn];
50 int main(){
51     while(~scanf("%s%d",str,&k)) {
52         memset(du,0,sizeof du);
53         memset(ans,0,sizeof ans);
54         sam.init();
55         for(int i = 0; str[i]; ++i) sam.extend(str[i] - ‘0‘);
56         for(int i = 0; i < sam.tot; ++i) {
57             memset(dp[i],0,sizeof dp[i]);
58             for(int j = 0; j < 10; ++j) if(sam.s[i].son[j] != -1) ++du[sam.s[i].son[j]];
59         }
60         //cout<<du[0]<<endl;
61         while(!q.empty());
62         for(int i = 0; i < sam.tot; ++i) if(!du[i]) q.push(i);
63         dp[0][0] = 1;
64         while(!q.empty()) {
65             int u = q.front();
66             q.pop();
67             for(int i = 0; i < 10; ++i) {
68                 int v = sam.s[u].son[i];
69                 if(v == -1) continue;
70                 if(--du[v] == 0) q.push(v);
71                 if(u == 0 && i == 0) continue;
72                 for(int j = 0; j < k; ++j)
73                     dp[v][(j*10 + i)%k] += dp[u][j];
74             }
75             for(int i = 0; i < k; ++i)
76                 ans[i] += dp[u][i];
77         }
78         ans[0]--;
79         for(int i = 0; str[i]; ++i)
80             if(str[i] == ‘0‘) {
81                 ans[0]++;
82                 break;
83             }
84         for(int i = 0; i < k-1; ++i)
85             printf("%d ",ans[i]);
86         printf("%d\n",ans[k-1]);
87     }
88     return 0;
89 }

时间: 2024-10-11 10:13:53

ZOJ 3891 K-hash的相关文章

ZOJ 3891 K-hash 后缀自动机

后缀自动机求不同的串,然后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 xocc

zoj 3715 K - Kindergarten Election

一个班有n个小朋友,要选一个班长,(n>=3),每个人不能投自己,给出每个人想要选的人,1号小朋友相当班长,如果一个小朋友不选自己 那么,自己可以给他bi个糖果让他选自己,那么请输出,最少花费多少个糖果 ,1号小朋友可以当上班长 开始的做法是贪心小的,那么问题很复杂,直接枚举小的是不符合条件的 后来想,枚举一号小朋友最后的票为k,那么其他人的票肯定小于等于k-1,如果有小朋友的选票高于k-1,那么先把投这个人的所有小朋友贿赂到小于k-1,按照需要的糖果数量 如果这个时候的选票大于k了,那么显然这

ZOJ 3599 K倍动态减法游戏

下面的文字辅助理解来自http://blog.csdn.net/tbl_123/article/details/24884861 博弈论中的 K倍动态减法游戏,难度较大,参看了好多资料才懵懂! 此题可以看作 Fibonacci 博弈的扩展,建议没弄懂 Fibonacci博弈的先学那个,个人整理 http://blog.csdn.net/tbl_123/article/details/24033245 : 而说扩展体现在数列不再是Fib数列,是根据 k 的值自行构造的,其它换汤不换药,具体构造方法

[Locked] Maximum Size Subarray Sum Equals k

Example 1: Given nums = [1, -1, 5, -2, 3], k = 3,return 4. (because the subarray [1, -1, 5, -2] sums to 3 and is the longest) Example 2: Given nums = [-2, -1, 2, 1], k = 1,return 2. (because the subarray [-1, 2] sums to 1 and is the longest) Follow U

Hash表的C++实现(转)

原文:Hash表(C++实现) 哈希表的几个概念: 映像:由哈希函数得到的哈希表是一个映像. 冲突:如果两个关键字的哈希函数值相等,这种现象称为冲突. 处理冲突的几个方法: 1.开放地址法:用开放地址处理冲突就是当冲突发生时,形成一个地址序列,沿着这个序列逐个深测,直到找到一个“空”的开放地址,将发生冲突的关键字值存放到该地址中去. 例如:hash(i)=(hash(key)+d(i)) MOD m (i=1,2,3,......,k(k<m-1)) d为增量函数,d(i)=d1,d2,d3,.

[poj3349]Snowflake Snow Snowflakes(hash)

Snowflake Snow Snowflakes Time Limit: 4000MS Memory Limit: 65536K Total Submissions: 37615 Accepted: 9882 Description You may have heard that no two snowflakes are alike. Your task is to write a program to determine whether this is really true. Your

js实现hash

由于项目中用到了hash,自己实现了一个. Hash = function () { } Hash.prototype = { constructor: Hash, add: function (k, v) { if (!this.hasOwnProperty(k)) { this[k] = v; } }, remove: function (k) { if (this.hasOwnProperty(k)) { delete this[k]; } }, update: function (k,

Java集合源码分析(七)HashMap&lt;K, V&gt;

一.HashMap概述 HashMap基于哈希表的 Map 接口的实现.此实现提供所有可选的映射操作,并允许使用 null 值和 null 键.(除了不同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同.)此类不保证映射的顺序,特别是它不保证该顺序恒久不变. 值得注意的是HashMap不是线程安全的,如果想要线程安全的HashMap,可以通过Collections类的静态方法synchronizedMap获得线程安全的HashMap. Map map = Coll

java.util.HashMap源码浅析之解决hash冲突

HashMap是java无论是企业管理系统还是web或者其他应用层的程序开发,都是应用比较多的一种数据结构,正好最近面试有问到与HashMap解决hash冲突的方式(本人菜比没答上来),现浅析源码以解惑 且记录,将来在项目上尽量避免此类问题的出现,大家都知道HashMap为key-value存储,在HashMap中,HashMap本身拥有一个Entry数组,Entry则存有key-value,且对于Hashmap来讲一个key只能对应一个value     首先是put方法