zoukankan      html  css  js  c++  java
  • 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

    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
    ",ans[k-1]);
    87     }
    88     return 0;
    89 }
    View Code
  • 相关阅读:
    【BFS】【HDOJ-1195】Open the Lock
    hadoop经典案例
    eclipse中下载maven插件解决办法
    eclipse中导入maven项目:org.apache.maven.archiver.MavenArchiver.getManifest(org.apache.maven.project.Maven
    mysql Alter 的问题
    代理模式:利用JDK原生动态实现AOP
    JAVA中关于set()和get()方法的理解及使用
    java 中 Cannot make a static reference to the non-static 解决方法
    maven clean 异常问题
    自定义scoll样式
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4756584.html
Copyright © 2011-2022 走看看