SOJ-4484-后缀数组
来源:互联网 发布:优化的南洋金珠会掉色 编辑:程序博客网 时间:2024/06/12 20:48
题目链接 : SOJ-4484
The Graver Robbers' Chronicles
Description
One day, Kylin Zhang and Wu Xie are trapped in a graveyard. They find an ancient piece of parchment with a cipher string. After discussion and analysis, they find the password is the total number of the cipher string's distinct substrings. Although Kylin Zhang is powerful and always help his friends get rid of danger, this time he is helpless beacause he is not good at math and programming. As a smart Acmer, can you help them solve this problem so that they can escape from this horrible graveyard.Input
The first line is an integer T stands for the number of test cases.Then T test case follow.For each test case there is one string.Constraints:T is no bigger than 30.The length of string is no bigger than 50000.Every string only contains lowercase letters.Output
For each test case, output the answer in a single line. one number saying the number of distinct substrings.Sample Input
2aaaaacacacSample Output
59Hint
For test case 2, the distinct substrings of 'cacac' are as follows:len = 1 : c , alen = 2 : ca , aclen = 3 : cac , acalen = 4 : caca , acaclen = 5 : cacacThus, total number of distinct substrings is 9.Author
_L
题目大意:给你一个字符串,求出有多少种不同的子串(连续)包括本身 见样例
题目思路: 看了很久的后缀数组了,,一直都不太懂怎么来的,之后用模板处理一些简单的问题,,这道题关键是对后缀数组height数组的理解,,具体我这里就不描述了,,答案就是所有的子串的个数减去height数组里的值,,这里会超int,,所以要用long long
AC代码:
#include<iostream>#include<cstdio>#include<algorithm>#include<cstring>using namespace std;const int maxn = 1e5;int cntA[maxn],sa[maxn],Rank[maxn],cntB[maxn],height[maxn],A[maxn],B[maxn],tsa[maxn];char ch[maxn];int n;void solve(){ for (int i = 0; i < 256; i ++) cntA[i] = 0; for (int i = 1; i <= n; i ++) cntA[ch[i-1]] ++; for (int i = 1; i < 256; i ++) cntA[i] += cntA[i - 1]; for (int i = n; i; i --) sa[cntA[ch[i-1]] --] = i; Rank[sa[1]] = 1; for (int i = 2; i <= n; i ++) { Rank[sa[i]] = Rank[sa[i - 1]]; if (ch[sa[i]-1] != ch[sa[i - 1]-1]) Rank[sa[i]] ++; } for (int l = 1; Rank[sa[n]] < n; l <<= 1) { for (int i = 0; i <= n; i ++) cntA[i] = 0; for (int i = 0; i <= n; i ++) cntB[i] = 0; for (int i = 1; i <= n; i ++) { cntA[A[i] = Rank[i]] ++; cntB[B[i] = (i + l <= n) ? Rank[i + l] : 0] ++; } for (int i = 1; i <= n; i ++) cntB[i] += cntB[i - 1]; for (int i = n; i; i --) tsa[cntB[B[i]] --] = i; for (int i = 1; i <= n; i ++) cntA[i] += cntA[i - 1]; for (int i = n; i; i --) sa[cntA[A[tsa[i]]] --] = tsa[i]; Rank[sa[1]] = 1; for (int i = 2; i <= n; i ++) { Rank[sa[i]] = Rank[sa[i - 1]]; if (A[sa[i]] != A[sa[i - 1]] || B[sa[i]] != B[sa[i - 1]]) Rank[sa[i]] ++; } } for (int i = 1, j = 0; i <= n; i ++) { if (j) j --; while (ch[i + j-1] == ch[sa[Rank[i] - 1] + j-1]) j ++; height[Rank[i]] = j; }}int main(){ int t;cin>>t; while(t--){ scanf("%s",ch); n=strlen(ch); solve(); long long ans = (long long)(1+n)*n/2; for(int i=1;i<=n;i++) ans-=(long long)height[i]; cout<<ans<<endl; } return 0;}
0 0
- SOJ-4484-后缀数组
- SOJ-2728(树状数组)
- 后缀树/后缀数组
- 后缀树 后缀数组
- 【后缀数组】后缀排序
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- 后缀数组
- linux下解决文件乱码问题及查看文件编码方法
- IntelliJ IDEA代码调试debug篇
- Ajax异步获取前台信息
- Jsonp解决ajax跨域问题
- Spring Boot(六)集成Spring session redis
- SOJ-4484-后缀数组
- 关于不再使用的Java对象手工指null是否有意义
- Android 权限管理
- Android 使用ContentResolver获取手机图片和照片的相关信息
- fir.im Weekly - 如何进行 Android App 性能优化
- ios与android与java通用的AES加解密
- iOS UITableViewController 添加一个固定的不能滚动的控件
- 常用插件
- win7,用vs2010编译libjpeg