题意:求最小循环节循环的次数。

题解:这个题其实可以直接用kmp去求最小循环节,然后在用总长度除以循环节。但是因为在练后缀数组,所以写的后缀数组版本。用倍增法会超时!!所以改用DC3法。对后缀数组还不是很理解,找了很多博客也没看懂到底有些数组到底记录的是啥,但他的实现过程很好理解,等我弄懂了再来给博客加注释吧。

先求出sa数组,height数组,rank数组(因为和c++库中某个东西重了所以写成rnk数组),数组一定要开3倍。接下来从小到大枚举循环节长度 i,如果长度i的子串刚好是重复了len/i次,应该满足len % i == 0 && rnk[0] - rnk[i] == 1 && height[rnk[0]] == len-i 这些条件。

  1 #include<cstdio>
2 #include<algorithm>
4 #include<iostream>
5 #include<cmath>
6 #include<cstring>
7 using namespace std;
8
9 #define F(x) ((x)/3+((x)%3==1?0:tb))
10 #define G(x) ((x)<tb?(x)*3+1:((x)-tb)*3+2)
11
12
13 //sa:字典序中排第i位的起始位置在s中第sa[i]
14
15 //rnk:就是s第i个位置的后缀是在字典序排第几
16
17 //height:字典序排i和i-1的后缀的最长公共前缀
18
19 const int MAXN = 3e6+10;//n*10
20 int sa[MAXN];
21 int rnk[MAXN];
22 int height[MAXN];
23 int n;
24 char s[MAXN];
25 int r[MAXN];
26 int wa[MAXN],wb[MAXN],wv[MAXN];
27 int wws[MAXN];
28
29 void sort(int *r,int *a,int *b,int n,int m)
30 {
31 int i;
32 for(i=0;i<n;i++) wv[i]=r[a[i]];
33 for(i=0;i<m;i++) wws[i]=0;
34 for(i=0;i<n;i++) wws[wv[i]]++;
35 for(i=1;i<m;i++) wws[i]+=wws[i-1];
36 for(i=n-1;i>=0;i--) b[--wws[wv[i]]]=a[i];
37 return;
38 }
39
40 int c0(int *r,int a,int b)
41 {
42 return r[a]==r[b]&&r[a+1]==r[b+1]&&r[a+2]==r[b+2];
43 }
44
45 int c12(int k,int *r,int a,int b)
46 {
47 if(k==2) return r[a]<r[b]||r[a]==r[b]&&c12(1,r,a+1,b+1);
48 else return r[a]<r[b]||r[a]==r[b]&&wv[a+1]<wv[b+1];
49 }
50
51 void dc3(int *r,int *sa,int n,int m)
52 {
53 int i,j,*rn=r+n,*san=sa+n,ta=0,tb=(n+1)/3,tbc=0,p;
54 r[n]=r[n+1]=0;
55 for(i=0;i<n;i++) if(i%3!=0) wa[tbc++]=i;
56 sort(r+2,wa,wb,tbc,m);
57 sort(r+1,wb,wa,tbc,m);
58 sort(r,wa,wb,tbc,m);
59 for(p=1,rn[F(wb[0])]=0,i=1;i<tbc;i++)
60 rn[F(wb[i])]=c0(r,wb[i-1],wb[i])?p-1:p++;
61 if(p<tbc) dc3(rn,san,tbc,p);
62 else for(i=0;i<tbc;i++) san[rn[i]]=i;
63 for(i=0;i<tbc;i++) if(san[i]<tb) wb[ta++]=san[i]*3;
64 if(n%3==1) wb[ta++]=n-1;
65 sort(r,wb,wa,ta,m);
66 for(i=0;i<tbc;i++) wv[wb[i]=G(san[i])]=i;
67 for(i=0,j=0,p=0;i<ta && j<tbc;p++)
68 sa[p]=c12(wb[j]%3,r,wa[i],wb[j])?wa[i++]:wb[j++];
69 for(;i<ta;p++) sa[p]=wa[i++];
70 for(;j<tbc;p++) sa[p]=wb[j++];
71 return;
72 }
73
74 void calheight(int *r, int *sa, int n)
75 {
76 // 此处n为实际长度
77 int i, j, k = 0;
78 // height[]的合法范围为 1~n, 其中0是结尾加入的字符
79 for (i = 1; i <= n; ++i) rnk[sa[i]] = i;
80 // 根据SA求RANK
81 for (i = 0; i < n; height[rnk[i++]] = k)
82 // 定义:h[i] = height[ RANK[i] ]
83 for (k ? k-- : 0, j = sa[rnk[i] - 1]; r[i + k] == r[j + k]; ++k);
84 //根据 h[i] >= h[i-1]-1 来优化计算height过程
85 return;
86 }
87
88 int main()
89 {
90 ios::sync_with_stdio(false);
91 cin.tie(0);
92 cout.tie(0);
93 while(cin>>s){
94 if(s[0]=='.') break;
95 int len=strlen(s);
96 for(int i=0;i<len;i++)
97 r[i]=s[i]-'a'+1;
98 r[len]=0;
99 dc3(r,sa,len+1,105);
100 calheight(r,sa,len);
101 int flag=0;
102 for(int i=1;i<=len;i++){
103 if(len%i==0&&rnk[0]==rnk[i]+1&&height[rnk[0]]==len-i){
104 cout<<len/i<<endl;
105 flag=1;
106 break;
107 }
108 }
109 if(!flag) cout<<1<<endl;
110 }
111 return 0;
112 }

POJ - 2406 Power Strings (后缀数组DC3版)的更多相关文章

  1. poj 2406 Power Strings 后缀数组解法

    连续重复子串问题 poj 2406 Power Strings http://poj.org/problem?id=2406 问一个串能否写成a^n次方这种形式. 虽然这题用kmp做比较合适,但是我们 ...

  2. poj 2406 Power Strings (后缀数组 || KMP)

    Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 28859   Accepted: 12045 D ...

  3. 【poj 2406】Power Strings 后缀数组DC3模板 【连续重复子串】

    Power Strings 题意 给出一个字符串s,求s最多由几个相同的字符串重复而成(最小循环节的重复次数) 思路 之前学习KMP的时候做过. 我的思路是:枚举字符串的长度,对于当前长度k,判断\( ...

  4. POJ 2406 Power Strings next数组循环节应用、

    题意:就给出个字符串做*的定义.a^0 = "" (the empty string) and a^(n+1) = a*(a^n).    题目要求n的最大值. 思路: 化简上面的 ...

  5. KMP POJ 2406 Power Strings

    题目传送门 /* 题意:一个串有字串重复n次产生,求最大的n KMP:nex[]的性质应用,感觉对nex加深了理解 */ /************************************** ...

  6. poj 2406 Power Strings (kmp 中 next 数组的应用||后缀数组)

    http://poj.org/problem?id=2406 Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submiss ...

  7. POJ 2406 Power Strings (KMP)

    Power Strings Time Limit: 3000MSMemory Limit: 65536K Total Submissions: 29663Accepted: 12387 Descrip ...

  8. poj 2406:Power Strings(KMP算法,next[]数组的理解)

    Power Strings Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 30069   Accepted: 12553 D ...

  9. KMP + 求最小循环节 --- POJ 2406 Power Strings

    Power Strings Problem's Link: http://poj.org/problem?id=2406 Mean: 给你一个字符串,让你求这个字符串最多能够被表示成最小循环节重复多少 ...

随机推荐

  1. WebApi 中请求的 JSON 数据字段作为 POST 参数传入

    使用 POST 方式请求 JSON 数据到服务器 WebAPI 接口时需要将 JSON 格式封装成数据模型接收参数.即使参数较少,每个接口仍然需要单独创建模型接收.下面方法实现了将 JSON 参数中的 ...

  2. 7.prometheus之查询API

    一.格式概述 二.表达式查询 2.1 Instant queries(即时查询) 2.2 范围查询 三.查询元数据 3.1 通过标签匹配器找到度量指标列表 3.2 获取标签名 3.3 查询标签值 四. ...

  3. .NET Core引入日志(Log4Net篇)

    Demo版本信息如下: VS:2019 框架:.Net Core 3.1 Log4Net:2.0.12 思维导图: [1]添加依赖项 通过nuget添加Log4Net [2]创建公共类 添加公共类Lo ...

  4. Azure Table Storage(一) : 简单介绍

    Azure Table Storage是什么: Azure Table Storage是隶属于微软Azure Storage这个大服务下的一个子服务, 这个服务在Azure上算是老字号了, 个人大概在 ...

  5. /etc/hosts导致的问题

    今天安装完成orzdba之后,执行./orzdba -l 报如下错误: Usage: Socket::inet_ntoa(ip_address_sv) at /var/lib/mysql/trunk/ ...

  6. mysqldump 的-T参数

    /usr/local/mysql/bin/mysqldump -uroot -T /tmp lina xuehao 把lina数据库中的xuehao表在tmp目录下备份出来两个文件,一个是纯数据.tx ...

  7. Jenkins自动部署spring boot

    Jenkins自动部署spring boot 背景介绍 本公司属于微小型企业,初期业务量不高,所有程序都写在一个maven项目里面,不过是多模块开发. 分了login模块,service模块,cms模 ...

  8. USB限流芯片,4.8A最大,过压关闭6V

    PW1503,PW1502是超低RDS(ON)开关,具有可编程的电流限制,以保护电源源于过电流和短路保护.它具有超温保护以及反向闭锁功能. PW1503,PW1502采用薄型(1毫米)5针薄型SOT2 ...

  9. Django的数据库读写分离

    Django的数据库读写分离 1.首先是配置数据库 在settings.py文件中增加多个数据库的配置: DATABASES = { 'default': { 'ENGINE': 'django.db ...

  10. STL_常用的算法

    STL_常用的算法 一.常用的查找算法 adjacent_find() adjacent_find(iterator beg, iterator end, _callback); 在iterator对 ...