思路

求本质不同的子串个数,总共重叠的子串个数就是height数组的和

总子串个数-height数组的和即可

代码

#include <cstdio>
#include <algorithm>
#include <cstring>
#define int long long
const int MAXN = 100000;
using namespace std;
int height[MAXN],sa[MAXN],ranks[MAXN],barrel[MAXN],n;
struct Node{
int pos,r[2];
}midx[MAXN],x[MAXN];
char s[MAXN];
int c_sort(int n,int lim){
for(int i=0;i<2;i++){
memset(barrel,0,sizeof(barrel));
for(int j=1;j<=n;j++)
barrel[x[j].r[i]]++;
for(int j=1;j<=lim;j++)
barrel[j]+=barrel[j-1];
for(int j=n;j>=1;j--)
midx[barrel[x[j].r[i]]--]=x[j];
for(int j=1;j<=n;j++)
x[j]=midx[j];
}
ranks[x[1].pos]=1;
int cnt=1;
for(int i=2;i<=n;i++){
if(x[i].r[0]==x[i-1].r[0]&&x[i].r[1]==x[i-1].r[1])
ranks[x[i].pos]=cnt;
else
ranks[x[i].pos]=++cnt;
}
return cnt;
}
void cal_sa(int n){
for(int i=1;i<=n;i++)
x[i]=(Node){i,s[i],0};
int cnt=c_sort(n,1500);
for(int i=1;cnt<n;i<<=1){
for(int j=1;j<=n;j++)
x[j]=(Node){j,(i+j<=n)?ranks[i+j]:0,ranks[j]};
cnt=c_sort(n,cnt);
}
for(int i=1;i<=n;i++)
sa[ranks[i]]=i;
for(int i=1,j=0,k;i<=n;height[ranks[i++]]=j)
for(j?j--:0,k=sa[ranks[i]-1];s[i+j]==s[j+k];j++);
}
void init(void){
memset(sa,0,sizeof(sa));
memset(height,0,sizeof(height));
memset(ranks,0,sizeof(ranks));
memset(x,0,sizeof(x));
memset(midx,0,sizeof(midx));
}
signed main(){
int T;
scanf("%lld",&T);
while(T--){
init();
scanf("%s",s+1);
n=strlen(s+1);
cal_sa(n);
int sum=0;
for(int i=2;i<=n;i++)
sum+=height[i];
printf("%lld\n",(n+1)*n/2-sum);
}
return 0;
}

SPOJ 694 DISUBSTR - Distinct Substrings的更多相关文章

  1. SPOJ 694&&SPOJ705: Distinct Substrings

    DISUBSTR - Distinct Substrings 链接 题意: 询问有多少不同的子串. 思路: 后缀数组或者SAM. 首先求出后缀数组,然后从对于一个后缀,它有n-sa[i]-1个前缀,其 ...

  2. 【SPOJ 694】Distinct Substrings 不相同的子串的个数

    不会FQ啊,没法评测啊,先存一下代码QAQ 2016-06-16神犇Menci帮我测过AC了,谢谢神犇Menci QwQ #include<cstdio> #include<cstr ...

  3. 【SPOJ 694】Distinct Substrings (更直接的求法)

    [链接]h在这里写链接 [题意] 接上一篇文章 [题解] 一个字符串所有不同的子串的个数=∑(len-sa[i]-height[i]) [错的次数] 0 [反思] 在这了写反思 [代码] #inclu ...

  4. 【SPOJ 694】Distinct Substrings

    [链接]h在这里写链接 [题意]     给你一个长度最多为1000的字符串     让你求出一个数x,这个x=这个字符串的不同子串个数; [题解]     后缀数组题.     把原串复制一份,加在 ...

  5. SPOJ 694 || 705 Distinct Substrings ( 后缀数组 && 不同子串的个数 )

    题意 : 对于给出的串,输出其不同长度的子串的种类数 分析 : 有一个事实就是每一个子串必定是某一个后缀的前缀,换句话说就是每一个后缀的的每一个前缀都代表着一个子串,那么如何在这么多子串or后缀的前缀 ...

  6. DISUBSTR - Distinct Substrings

    DISUBSTR - Distinct Substrings no tags  Given a string, we need to find the total number of its dist ...

  7. SPOJ 694 Distinct Substrings/SPOJ 705 New Distinct Substrings(后缀数组)

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

  8. SPOJ - DISUBSTR Distinct Substrings (后缀数组)

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

  9. 后缀数组:SPOJ SUBST1 - New Distinct Substrings

    Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...

随机推荐

  1. 31网络通信之Select模型

    多路复用并发模型  -- select #include<sys/select.h> #include<sys/time.h> int select(int maxfd,  f ...

  2. 编写python的程序

    执行python程序有两种方式:      1.交互式环境:输入代码立即执行              优点:调试程序方便              缺点:无法永久保存程序      2.代码写入文件 ...

  3. python: numpy--函数 shape用法

    http://blog.csdn.net/u010758410/article/details/71554224 shape函数是numpy.core.fromnumeric中的函数,它的功能是查看矩 ...

  4. 随机模拟(MCMC)

    http://cos.name/2013/01/lda-math-mcmc-and-gibbs-sampling/ http://blog.csdn.net/lin360580306/article/ ...

  5. JavaScript--详解typeof的用法

    typeof定义      typeof是一元运算符,用来返回操作参数的类型(不是值)    检查一个变量是否存在,是否有值      typeof在两种情况下会返回"undefined&q ...

  6. 电脑已连接wifi的密码查询

    有时候,想登陆自己家的无线网络(尤其朋友来家里突然要连接无线网络),脑子刹那间一片空白想不起来密码,怎么办呢? 其实,我们可以通过电脑来查看网络的密码,现在分享如何在笔记本电脑上查看连接过的无线网络密 ...

  7. 入坑tensorflow

    win10 CPU版,anaconda prompt命令行一句话,pip install --upgrade tensorflow搞定.比caffe好装一万倍. gpu版没装成,首先这个笔记本没装cu ...

  8. Linux中常用的50个命令

    1. [命令]:cat [功能说明]: concatenate files and print on the standard output #连接文件并打印到标准输出,有标准输出的都可以用重定向定向 ...

  9. Log4j基础知识

    Log4J是Apache的一个开放源代码的项目.通过使用Log4J,程序员可以控制日志信息输送的目的地,包括控制台,文件,GUI组件和NT事件记录器,也可以控制每一条日志的输出格式,或通过定义每一条日 ...

  10. document.createDocumentFragment 以及创建节点速度比较

    document.createDocumentFragment document.createDocumentFragment()方法创建一个新空白的DocumentFragment对象. Docum ...