spoj New Distinct Substrings
vjudge原地爆炸...
题意:求一个字符串不同的子串的个数
策略:后缀数组
利用后缀数组的sa和height两个功能强大的数组,我们可以实现上述操作
首先有个很显然的结论:一个字符串的所有子串=它后缀的所有前缀
这是很显然的,因为一个后缀的前缀遍历了所有以该后缀起点为起点的字符串的子串,那么如果我们遍历所有后缀的,就能找出这个字符串的所有子串了
所以对于一个起点为sa[i]的字符串,最多能提供的贡献就是l-sa[i]+1,而再考虑重复字符串的个数,也就是这个后缀所有的与其他后缀最长的公共前缀,这个后缀的贡献就是l-sa[i]+1-height[i]
然后累计即可
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
int sa[50005];
int rk[50005];
int height[50005];
int f1[50005];
int f2[50005];
int f3[50005];
int has[50005];
char s[50005];
int l,m=127;
void init()
{
memset(sa,0,sizeof(sa));
memset(rk,0,sizeof(rk));
memset(has,0,sizeof(has));
memset(f1,0,sizeof(f1));
memset(f2,0,sizeof(f2));
memset(f3,0,sizeof(f3));
memset(height,0,sizeof(height));
m=127;
}
void turnit()
{
memcpy(f3,f1,sizeof(f3));
memcpy(f1,f2,sizeof(f1));
memcpy(f2,f3,sizeof(f2));
}
void get_sa()
{
for(int i=1;i<=l;i++)
{
f1[i]=s[i];
has[f1[i]]++;
}
for(int i=2;i<=m;i++)
{
has[i]+=has[i-1];
}
for(int i=l;i>=1;i--)
{
sa[has[f1[i]]--]=i;
}
for(int k=1;k<=l;k<<=1)
{
int tot=0;
for(int i=l-k+1;i<=l;i++)
{
f2[++tot]=i;
}
for(int i=1;i<=l;i++)
{
if(sa[i]>k)
{
f2[++tot]=sa[i]-k;
}
}
for(int i=1;i<=m;i++)
{
has[i]=0;
}
for(int i=1;i<=l;i++)
{
has[f1[i]]++;
}
for(int i=2;i<=m;i++)
{
has[i]+=has[i-1];
}
for(int i=l;i>=1;i--)
{
sa[has[f1[f2[i]]]--]=f2[i];
f2[i]=0;
}
turnit();
f1[sa[1]]=1;
tot=1;
for(int i=2;i<=l;i++)
{
if(f2[sa[i]]==f2[sa[i-1]]&&f2[sa[i]+k]==f2[sa[i-1]+k])
{
f1[sa[i]]=tot;
}else
{
f1[sa[i]]=++tot;
}
}
if(tot==l)
{
break;
}
m=tot;
}
for(int i=1;i<=l;i++)
{
rk[sa[i]]=i;
}
int f=0;
for(int i=1;i<=l;i++)
{
if(rk[i]==1)
{
continue;
}
if(f)
{
f--;
}
int j=sa[rk[i]-1];
while(s[i+f]==s[j+f])
{
f++;
}
height[rk[i]]=f;
}
}
void solve()
{
int ss=0;
for(int i=1;i<=l;i++)
{
ss-=l-sa[i]+1-height[i];
}
printf("%d\n",ss);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
init();
scanf("%s",s+1);
l=strlen(s+1);
get_sa();
solve();
}
return 0;
}
spoj New Distinct Substrings的更多相关文章
- 【SPOJ】Distinct Substrings(后缀自动机)
[SPOJ]Distinct Substrings(后缀自动机) 题面 Vjudge 题意:求一个串的不同子串的数量 题解 对于这个串构建后缀自动机之后 我们知道每个串出现的次数就是\(right/e ...
- 【SPOJ】Distinct Substrings/New Distinct Substrings(后缀数组)
[SPOJ]Distinct Substrings/New Distinct Substrings(后缀数组) 题面 Vjudge1 Vjudge2 题解 要求的是串的不同的子串个数 两道一模一样的题 ...
- 【SPOJ】Distinct Substrings
[SPOJ]Distinct Substrings 求不同子串数量 统计每个点有效的字符串数量(第一次出现的) \(\sum\limits_{now=1}^{nod}now.longest-paren ...
- SPOJ 694. Distinct Substrings (后缀数组不相同的子串的个数)转
694. Distinct Substrings Problem code: DISUBSTR Given a string, we need to find the total number o ...
- SPOJ 694 Distinct Substrings
Distinct Substrings Time Limit: 1000ms Memory Limit: 262144KB This problem will be judged on SPOJ. O ...
- 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 ...
- SPOJ - DISUBSTR Distinct Substrings (后缀数组)
Given a string, we need to find the total number of its distinct substrings. Input T- number of test ...
- SPOJ 705 Distinct Substrings(后缀数组)
[题目链接] http://www.spoj.com/problems/SUBST1/ [题目大意] 给出一个串,求出不相同的子串的个数. [题解] 对原串做一遍后缀数组,按照后缀的名次进行遍历, 每 ...
- spoj 694. Distinct Substrings 后缀数组求不同子串的个数
题目链接:http://www.spoj.com/problems/DISUBSTR/ 思路: 每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数.如果所有的后缀按照su ...
- 后缀数组 SPOJ 694 Distinct Substrings
题目链接 题意:给定一个字符串,求不相同的子串的个数 分析:我们能知道后缀之间相同的前缀的长度,如果所有的后缀按照 suffix(sa[0]), suffix(sa[1]), suffix(sa[2] ...
随机推荐
- 【1】【JUC】JDK1.8源码分析之ArrayBlockingQueue,LinkedBlockingQueue
概要: ArrayBlockingQueue的内部是通过一个可重入锁ReentrantLock和两个Condition条件对象来实现阻塞 注意这两个Condition即ReentrantLock的Co ...
- 微信公众号绑定服务器 Flask版
python 代码 from flask import Flask, request from flask_cors import CORS app = Flask(__name__) app.app ...
- iscroll.js 手机上下滑动 加载更多
html <!DOCTYPE html> <html> <head> <title>下拉上拉刷新页面代码</title> <meta ...
- Python写日志
import logging import ResultFolder logger = logging.getLogger() logger.setLevel(logging.DEBUG) def C ...
- C# 部分类使用partial修饰
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace pati ...
- MGR架构~单写模式架构的搭建
一 简介 :MGR一直没有时间测试,今天咱们来初步了解搭建一下呗 二 环境: mysql5.7.20 单台机器 启动三实例 三 mysql 搭建: 1 建立相关目录+ mkdir -p /data ...
- iOS视频流开发(2)—视频播放
承上篇,本篇文章主要介绍iOS视频播放需要用到的类.以及他们的使用场景和开发中遇到的问题. MPMoviePlayerViewController MP简介 iOS提供MPMoviePlayerCon ...
- aar jar包打包
使用Android Studio Module的方式编译出aar和jar包: aar包:打aar包时,gradle compile依赖编译进来的包不会被打到aar包中,所以接入aar的应用仍然需要添加 ...
- mac系统在配置navicat时连接数据的时候提示can't connect to mysql server on '127.0.0.1'
新建数据库连接的时候,将默认的端口号更改掉,改为3307,即可解决这个问题. 具体是为什么我也不清楚,我自己想的一个可能就是mac电脑 上的某个程序可能已经占用了3306那个默认的端口,因 ...
- Maven入门-依赖管理(Jar包管理)(二)
1 依赖管理(Jar包管理) 1.添加依赖