HDU_1457_后缀自动机四·重复旋律7
2018-06-17 21:48:06来源:未知 阅读 ()
#1457 : 后缀自动机四·重复旋律7
描述
小Hi平时的一大兴趣爱好就是演奏钢琴。我们知道一段音乐旋律可以被表示为一段数构成的数列。
神奇的是小Hi发现了一部名字叫《十进制进行曲大全》的作品集,顾名思义,这部作品集里有许多作品,但是所有的作品有一个共同特征:只用了十个音符,所有的音符都表示成0-9的数字。
现在小Hi想知道这部作品中所有不同的旋律的“和”(也就是把串看成数字,在十进制下的求和,允许有前导0)。答案有可能很大,我们需要对(10^9 + 7)取摸。
解题方法提示
输入
第一行,一个整数N,表示有N部作品。
接下来N行,每行包含一个由数字0-9构成的字符串S。
所有字符串长度和不超过 1000000。
输出
共一行,一个整数,表示答案 mod (10^9 + 7)。
- 样例输入
-
2 101 09
- 样例输出
-
131
- 给出n个数串然后求出所有数串中所有子数串的sum
- 如果一个一个的字串来求就要造n个自动机
- 至于计算过程就是对于每一个节点延伸到下一个节点过程中将当前sum乘10之后加上到下一个节点的单个数乘以当前字串出现次数的乘积即可
- 那么这样的计算方式没有问题但是建立n个SAM耗时太长了
- 那么我们可不可以减少SAM的建立呢?
- 还是可以的,只要把全部的字串用“:”链接,之后再建立SAM即可
- 在这里我们总的计算方式是不变的
- 但是对于一个出现过“:”的字串是不应该进行计算的,因为如果出现“:”就代表着当前字串包含至少两个原始串
- 所以我们现在的问题是怎样辨别当前字串中是否出现过“:”
- 我们可以通过在字串出现次数这里做文章,对于字串中出现“:”的我们可以通过把字串出现次数标记为0,在进行计算的过程中我们相当于没有对于当前待操作节点sum进行更新即可。那么这里对于cnt的计算可以通过普通的拓扑排序进行,在排序过程中只对于0到9的的路径进行记录
- 之后就是从根节点进行一次bfs即可
- 我的代码里把以上的cnt的计算和计算最终结果的bfs合并在一起了,用一个拓扑解决了
1 #include <iostream> 2 #include <string> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <climits> 7 #include <cmath> 8 #include <vector> 9 #include <queue> 10 #include <stack> 11 #include <set> 12 #include <map> 13 using namespace std; 14 typedef long long LL ; 15 typedef unsigned long long ULL ; 16 const int maxn = 1e6 + 10 ; 17 const int inf = 0x3f3f3f3f ; 18 const int npos = -1 ; 19 const LL mod = 1e9 + 7 ; 20 const int mxx = 100 + 5 ; 21 const double eps = 1e-6 ; 22 const double PI = acos(-1.0) ; 23 struct topo{ 24 int len, st; 25 topo(int x, int y){ 26 len=x; st=y; 27 } 28 }; 29 bool topocmp(const topo &l, const topo &r){ 30 return l.len<r.len; 31 } 32 struct SAM{ 33 struct node{ 34 int len; 35 int link, go[26]; 36 LL cnt, val; 37 }; 38 node state[maxn<<1]; 39 int n, tot, root, last; 40 void init(char *str){ 41 n=strlen(str); 42 tot=1; 43 root=1; 44 last=1; 45 memset(&state,0,sizeof(state)); 46 state[root].cnt=1LL; 47 } 48 void extend(int w){ 49 tot++; 50 int p=last; 51 int np=tot; 52 state[np].len=state[p].len+1; 53 state[np].cnt=0LL; 54 // state[np].cnt=(w==10?1LL:0LL); 55 state[np].val=0LL; 56 while(p && state[p].go[w]==0){ 57 state[p].go[w]=np; 58 p=state[p].link; 59 } 60 if(p==0){ 61 state[np].link=root; 62 }else{ 63 int q=state[p].go[w]; 64 if(state[p].len+1==state[q].len){ 65 state[np].link=q; 66 }else{ 67 tot++; 68 int nq=tot; 69 state[nq].len=state[p].len+1; 70 state[nq].cnt=state[q].cnt; 71 state[nq].val=0LL; 72 memcpy(state[nq].go,state[q].go,sizeof(state[q].go)); 73 state[nq].link=state[q].link; 74 state[q].link=nq; 75 state[np].link=nq; 76 while(p && state[p].go[w]==q){ 77 state[p].go[w]=nq; 78 p=state[p].link; 79 } 80 } 81 } 82 last=np; 83 } 84 void build(char *str){ 85 init(str); 86 for(int i=0;i<n;i++) 87 extend(str[i]-'0'); 88 } 89 LL calsum(void){ 90 LL ans=0LL; 91 std::vector< topo > v; 92 for(int i=root;i<=tot;i++) 93 v.push_back(topo(state[i].len,i)); 94 sort(v.begin(),v.end(), topocmp); 95 int sz=v.size(), p, q; 96 for(int i=0;i<sz;i++){ 97 p=v[i].st; 98 for(int j=0;j<10;j++) 99 if(state[p].go[j]){ 100 q=state[p].go[j]; 101 state[q].cnt+=state[p].cnt; 102 state[q].val=(state[q].val + ((10LL*state[p].val)%mod + ((LL)j*state[p].cnt)%mod)%mod)%mod; 103 } 104 ans=(ans+state[p].val)%mod; 105 } 106 ans=(ans+mod)%mod; 107 return ans; 108 } 109 }; 110 SAM A; 111 int n, lth; 112 char str[maxn]; 113 int main(){ 114 // freopen("in.txt","r",stdin); 115 // freopen("out.txt","w",stdout); 116 while(~scanf("%d",&n)){ 117 lth=0; 118 for(int i=1;i<=n;i++,lth++){ 119 scanf("%s",str+lth); 120 lth=strlen(str); 121 if(i==n){break;} 122 str[lth]=':'; 123 } 124 A.build(str); 125 printf("%lld\n",A.calsum()); 126 } 127 return 0; 128 }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:HDU_5510_Bazinga
- HDU-2955-Robberies(0-1背包) 2020-03-30
- hdu1455 拼木棍(经典dfs) 2020-02-29
- anniversary party_hdu1520 2020-02-16
- hdu1062 text reverse 2020-01-27
- hdu4841 2020-01-26
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash