spoj 694

给出一个字符串,求字符串中不相同的子串个数。

我们可以知道,字符串中的每个子串都是某个后缀的前缀,于是题目转化为求不相同的后缀的前缀问题。对于每一个SA[k]SA[k]开始的后缀,将会增加n−SA[k]+1n-SA[k]+1个后缀,而其中height[k]height[k]个是和前面的字符串的前缀是相同的。所以答案就是所有n−SA[k]+1−height[k]n-SA[k]+1-height[k]的总和

#include<cstdio>
#include<cstring>
#include<algorithm>
#define ms(i, j) memset(i, j, sizeof i)
#define FN2 "spoj694"
using namespace std;const int MAXN = 1000 + 5;char s[MAXN];
int n, m, a[MAXN], tp[MAXN], rk[MAXN], SA[MAXN], tax[MAXN], height[MAXN];bool cmp(int *f, int i, int k) {return f[SA[i]]==f[SA[i-1]]&&f[SA[i]+k]==f[SA[i-1]+k];}
void build() {for (int i=0;i<m;i++) tax[i] = 0;for (int i=0;i<n;i++) tax[rk[i]=a[i]]++;for (int i=1;i<m;i++) tax[i] += tax[i-1];for (int i=n-1;i>=0;i--) SA[--tax[rk[i]]] = i;int p;for (int k=1;k<=n;k*=2) {p = 0;for (int i=n-k;i<n;i++) tp[p++] = i;for (int i=0;i<n;i++) if (SA[i]>=k) tp[p++] = SA[i]-k;for (int i=0;i<m;i++) tax[i] = 0;for (int i=0;i<n;i++) tax[rk[tp[i]]]++;for (int i=1;i<m;i++) tax[i] += tax[i-1];for (int i=n-1;i>=0;i--) SA[--tax[rk[tp[i]]]] = tp[i];swap(rk, tp), p = 0, rk[SA[0]] = 0;for (int i=1;i<n;i++) rk[SA[i]] = cmp(tp, i, k) ? p : ++p;if (++p>=n) break;m = p;}
}
void getH() {int k = 0;for (int i=0;i<n;i++) {if (k) k--;int j = SA[rk[i]-1];while (a[i+k]==a[j+k]) k++;height[rk[i]] = k;}
}
void init() {scanf("%s", s);n = strlen(s) + 1;for (int i=0;i<n-1;i++) a[i] = s[i];m = 128, a[n-1] = 0;
}
void solve() {build(), getH();int ans = 0;for (int i=1;i<n;i++) {ans += (n-1) - SA[i] - height[i];}printf("%d\n", ans);
}
int main() {#ifndef ONLINE_JUDGEfreopen(FN2".in","r",stdin);freopen("1.out","w",stdout);#endifint kase; scanf("%d", &kase);while(kase--) init(), solve();return 0;
}

|spoj 694|后缀数组|Distinct Substrings相关推荐

  1. New Distinct Substrings(后缀数组)

    New Distinct Substrings(后缀数组) 给定一个字符串,求不相同的子串的个数.\(n<=50005\). 显然,任何一个子串一定是后缀上的前缀.先(按套路)把后缀排好序,对于 ...

  2. SPOJ 220 Relevant Phrases of Annihilation(后缀数组+二分答案)

    [题目链接] http://www.spoj.pl/problems/PHRASES/ [题目大意] 求在每个字符串中出现至少两次的最长的子串 [题解] 注意到这么几个关键点:最长,至少两次,每个字符 ...

  3. SPOJ 7258 SUBLEX 后缀数组_二分答案_前缀和

    SPOJ 7258 SUBLEX 后缀数组_二分答案_前缀和 Code: #include <cstdio> #include <algorithm> #include < ...

  4. CSU1632Repeated Substrings(后缀数组/最长公共前缀)

    题意就是求一个字符串的重复出现(出现次数>=2)的不同子串的个数. 标准解法是后缀数组.最长公共前缀的应用,对于样例aabaab,先将所有后缀排序: aab 3    aabaab 1    a ...

  5. SPOJ - PHRASES Relevant Phrases of Annihilation —— 后缀数组 出现于所有字符串中两次且不重叠的最长公共子串...

    题目链接:https://vjudge.net/problem/SPOJ-PHRASES PHRASES - Relevant Phrases of Annihilation no tags  You ...

  6. POJ1226 Substrings(二分+后缀数组)

    题意:给n个字符串,求最长的子串,满足它或它的逆置出现在所有的n个字符串中. 把n个字符串及其它们的逆置拼接,中间用不同字符隔开,并记录suffix(i)是属于哪个字符串的: 跑后缀数组计算heigh ...

  7. POJ - 3415 Common Substrings(后缀数组+单调栈)

    题目链接:点击查看 题目大意:给出两个字符串,再给出一个k,问两个字符串中长度大于等于k的公共子串有多少个(种类可重复) 题目分析:因为涉及到了子串问题,先用后缀数组跑出height数组来,接下来如果 ...

  8. 【2012百度之星/资格赛】H:用户请求中的品牌 [后缀数组]

    时间限制: 1000ms 内存限制: 65536kB 描述 馅饼同学是一个在百度工作,做用户请求(query)分析的同学,他在用户请求中经常会遇到一些很奇葩的词汇.在比方说"johnsonj ...

  9. HDU 5769 Substring(后缀数组)

    Substring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total ...

最新文章

  1. 数据驱动:新药物发现知识图
  2. 3句话概括 PUT/POST 的区别
  3. NAND Flash和NOR Flash的区别
  4. 大讲台大数据特训学习笔记
  5. IOS 程序猿 UITbleView 篇
  6. android 蓝牙设置平板电脑,java – BlueCove,笔记本电脑和带蓝牙的Android平板电脑
  7. oracle 数据库,用户管理以及表空间等相关基础操作
  8. Android APK反编译就这么简单 详解
  9. 计算机活动宣传稿,畅想科技,创造梦想 ——东华大学计算机科学与技术学院第十一届图灵科技文化节通讯稿...
  10. 深层神经网络——分类、回归的损失函数
  11. java中常量有初始化值吗,Java基础_变量、常量
  12. 从零开始实现 AlphaGo(一)
  13. 2021年dedecms伪原创插件,织梦AI文章伪原创插件使用方法
  14. 【论文笔记】AutoML: A survey of the state-of-the-art(下篇)
  15. CyanogenMod 和 Cyanogen OS 对比
  16. 如何在 AWS 云中从 Amazon EC2 启动 RHEL 8?
  17. 利用python识别身份证号后获取年龄和性别信息
  18. xv6 6.S081 Lab3: alloc
  19. Python argparse.ArgumentParser的add_argument()用法
  20. 联想涉密专用计算机 字体,Lenovo出厂高分屏笔记本高分辨率下字体模糊的解决方法...

热门文章

  1. wc 一个进程结果是2_用开放的wc创建一个Web组件
  2. 皮马印第安人糖尿病数据集分享
  3. FFMPEG 压缩视频文件
  4. 借一道leetcode思考总结map/set的应用及区别
  5. mysql 5.7.17 zip_win10下mysql 5.7.17 zip压缩包版安装教程
  6. 如何让google,baidu,Yahoo收录你的网站
  7. 2022-05-25 网工进阶(七)OSPF-影响邻居关系建立的因素、路由撤销、路由汇总、路由过滤、Silent-Interface、报文认证
  8. IMM管理口收集日志
  9. linux连接oracle的日志,linux shell脚本连接oracle查询数据插入文件和日志文件中
  10. Numpy API 速查表