SPOJ 705 New Distinct Substrings 后缀数组
2016-02-15 11:20
363 查看
LINK: http://www.spoj.com/problems/SUBST1/
bzoj 3230做着做着就滚来做这题了。。
求一个字符串的不等(?)子串个数。
比如字符串ababa,其排好序的后缀是:
然后每个后缀可以产生以其长度n−sai+1为个数的子串,但和有序上一个后缀会产生重复子串,个数为与其的公共前缀长度,因此答案为
∑n−sai+1−heighti
其中sa和height都从1开始。
不过下面的程序是从0开始的。。
这程序其实就是bzoj3230稍微改了下。。
奇怪了怎么改都是0.02s
CCCCC
ABABA
9
bzoj 3230做着做着就滚来做这题了。。
求一个字符串的不等(?)子串个数。
比如字符串ababa,其排好序的后缀是:
a aba ababa ba baba
然后每个后缀可以产生以其长度n−sai+1为个数的子串,但和有序上一个后缀会产生重复子串,个数为与其的公共前缀长度,因此答案为
∑n−sai+1−heighti
其中sa和height都从1开始。
不过下面的程序是从0开始的。。
这程序其实就是bzoj3230稍微改了下。。
奇怪了怎么改都是0.02s
#include <cstdio> #include <cstring> #include <algorithm> using namespace std; #define rep(i,j,k) for(int i=j;i<k;i++) #define FOR(i,j,k) for(int i=j;i<=k;i++) const int N = 50100; typedef long long ll; ll read() { ll s = 0, f = 1; char ch = getchar(); for (; ch < '0' || ch > '9'; ch = getchar()) if (ch == '-') f = -1; for (; '0' <= ch && ch <= '9'; ch = getchar()) s = s * 10 + ch - '0'; return s * f; } char str ; struct SuffixArray { char r ; int n, m, num , z ; int sa , rk , h ; int wa , wb , wv , c ; ll s ; private: SuffixArray(){} public: SuffixArray(char *_r, int _n, int _m) { rep(i,0,_n) r[i]=_r[i]; r[_n] = 0; n = _n + 1; m = _m; da(); calHeight(); init(); } void *operator new(size_t) { static SuffixArray r; return &r; } void sort(int *sa, int *x, int *y, int n, int m) { rep(i,0,m) c[i] = 0; rep(i,0,n) c[x[i]]++; rep(i,1,m) c[i] += c[i-1]; for(int i=n-1;i>=0;i--) sa[--c[x[i]]] = y[i]; } void da() { int j, p, *x = wa, *y = wb, *t; rep(i,0,n) x[i]=r[i],z[i]=i; sort(sa, x, z, n, m); for(j=1,p=1;p<n;j*=2,m=p) { p=0; rep(i,n-j,n) y[p++] = i; rep(i,0,n) if(sa[i]>=j) y[p++]=sa[i]-j; rep(i,0,n) wv[i]=x[y[i]]; sort(sa, wv, y, n, m); swap(x,y);p=1;x[sa[0]]=0; rep(i,1,n) x[sa[i]]=y[sa[i-1]]==y[sa[i]]&&y[sa[i-1]+j]==y[sa[i]+j]?p-1:p++; } } void calHeight() { int k = 0; rep(i,0,n) rk[sa[i]] = i; rep(i,0,n-1) { if(k)k--; for(int j=sa[rk[i]-1];r[i+k]==r[j+k];k++); h[rk[i]]=k; } rep(i,1,n) s[i] = s[i - 1] + (n - 1 - sa[i]) - h[i]; } }; int main() { int n, m, l, r, id; ll ans = 0, t, l1, r1, l2, r2; SuffixArray *sa; log[0] = -1; rep(i,1,N) log[i] = log[i / 2] + 1; n = read(); while (n--) { scanf("%s", str); m = strlen(str); sa = new SuffixArray(str, m, 255); printf("%d\n", sa->s[m]); } return 0; }
SUBST1 - New Distinct Substrings
Given a string, we need to find the total number of its distinct substrings.Input
T- number of test cases. T<=20; Each test case consists of one string, whose length is <= 50000Output
For each test case output one number saying the number of distinct substrings.Example
Input:
2CCCCC
ABABA
Output:
59
相关文章推荐
- 使用 Gradle 管理你的 Android Studio 工程
- SQLGetData Function
- keyboard_man的理想
- Selenium webdriver常用命令汇总
- gem淘宝镜像,ios swift jazzy文档生成 教程
- linux学习笔记七:安装中文man手册
- iOS NSInteger/NSUInteger与int/unsigned int、long/unsigned long之间的区别!Nsnumber
- 利用VBoxManage对虚拟机格式vdi、vmdk、vhd进行互转
- JQ N级导航
- Linq NOT IN (或 NOT EXISTS)、LEFT JOIN踩坑记
- JAVA反射机制的应用场景
- windows和linux监听端口数据的方法
- linux学习笔记六:加载USB移动硬盘(NTFS格式)
- linux调试工具gdb初步学习
- HTML5与php实现消息推送功能
- mass的domReady方案
- 计算几何
- YUM常用命令介绍
- linux学习笔记五:加载U盘
- chomp用法