CSL 的密码(后缀数组)
CSL 的密码
解题思路
后缀数组。对于每一个后缀\(k\)都有\(n - k + 1\)个前缀,把所有不和前一个(排序后的)公共且长度大于\(m\)的前缀个数加起来。
代码如下
#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 100005;
int x[N], y[N], c[N], sa[N];
char s[N];
int n, m;
void get_SA()
{
    for(int i = 1; i <= m; i ++) c[i] = 0;
    for(int i = 1; i <= n; i ++) c[x[i] = s[i]] ++;
    for(int i = 1; i <= m; i ++) c[i] += c[i - 1];
    for(int i = n; i >= 1; i --) sa[c[x[i]] --] = i;
    for(int k = 1; k <= n; k <<= 1){
        int num = 0;
        for(int i = n - k + 1; i <= n; i ++) y[++num] = i;
        for(int i = 1; i <= n; i ++) if(sa[i] > k) y[++num] = sa[i] - k;
        for(int i = 1; i <= m; i ++) c[i] = 0;
        for(int i = 1; i <= n; i ++) c[x[i]] ++;
        for(int i = 1; i <= m; i ++) c[i] += c[i - 1];
        for(int i = n; i >= 1; i --) sa[c[x[y[i]]] --] = y[i], y[i] = 0;
        num = 1;
        swap(x, y);
        x[sa[1]] = num;
        for(int i = 2; i <= n; i ++){
            if(sa[i] + k <= n && sa[i - 1] + k <= n)
                x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k])? num: ++num;
            else
                x[sa[i]] = ++num;
        }
        if(num == n)
            break;
        m = num;
    }
}
int height[N], rk[N];
void get_h()
{
    int k = 0;
    for(int i = 1; i <= n; i ++) rk[sa[i]] = i;
    for(int i = 1; i <= n; i ++){
        if(rk[i] == 1) continue;
        if(k) --k;
        int j = sa[rk[i] - 1];
        while(i + k <= n && j + k <= n && s[i + k] == s[j + k]) ++k;
        height[rk[i]] = k;
    }
}
int main()
{
    int len;
    scanf("%d%d", &n, &len);
    m = 'z';
    scanf("%s", s + 1);
    get_SA();
    get_h();
    ll ans = 0;
    for(int i = 1; i <= n; i ++){
        if(sa[i] > n - len + 1) continue;
        int num = n - sa[i] + 1 - len + 1;
        ans += num - max(0, height[i] - len + 1);
    }
    printf("%lld\n", ans);
    return 0;
}
CSL 的密码(后缀数组)的更多相关文章
- C、CSL 的密码 【set暴力 || 后缀数组】 (“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛 )
		题目传送门:https://ac.nowcoder.com/acm/contest/551/C 题目描述 众所周知,CSL 最喜欢的密码是 ******.于是有一天…… 为了改变这一点,他决定 ... 
- BZOJ3172      后缀数组
		题意:求出一篇文章中每个单词的出现次数 对样例的解释: 原文是这样的: a aa aaa 注意每个单词后都会换行 所以a出现次数为6,aa为3 (aa中一次,aaa中两次),aaa为1 标准解法好像是 ... 
- 后缀数组的倍增算法(Prefix Doubling)
		后缀数组的倍增算法(Prefix Doubling) 文本内容除特殊注明外,均在知识共享署名-非商业性使用-相同方式共享 3.0协议下提供,附加条款亦可能应用. 最近在自学习BWT算法(Burrows ... 
- BZOJ 4199: [Noi2015]品酒大会 [后缀数组 带权并查集]
		4199: [Noi2015]品酒大会 UOJ:http://uoj.ac/problem/131 一年一度的“幻影阁夏日品酒大会”隆重开幕了.大会包含品尝和趣味挑战两个环节,分别向优胜者颁发“首席品 ... 
- BZOJ 1692: [Usaco2007 Dec]队列变换 [后缀数组 贪心]
		1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1383 Solved: 582[Submit][St ... 
- POJ3693 Maximum repetition substring [后缀数组 ST表]
		Maximum repetition substring Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9458 Acc ... 
- POJ1743 Musical Theme [后缀数组]
		Musical Theme Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 27539 Accepted: 9290 De ... 
- 后缀数组(suffix array)详解
		写在前面 在字符串处理当中,后缀树和后缀数组都是非常有力的工具. 其中后缀树大家了解得比较多,关于后缀数组则很少见于国内的资料. 其实后缀数组是后缀树的一个非常精巧的替代品,它比后缀树容易编程实现, ... 
- 【UOJ #35】后缀排序 后缀数组模板
		http://uoj.ac/problem/35 以前做后缀数组的题直接粘模板...现在重新写一下模板 注意用来基数排序的数组一定要开到N. #include<cstdio> #inclu ... 
随机推荐
- eclipse的maven配置及本地仓库配置
			一.下载maven并解压 下载地址:http://maven.apache.org/download.cgi 解压后如下: 二.配置环境变量 配置MAVEN_HOME 再path中添加 安装成功 三. ... 
- 使用requests_html抓取数据
			from requests_html import HTMLSession import json class YejiCollege: def __init__(self, url): self.u ... 
- 0x3f3f3f3f 0xbfbfbfbf 等的原理及应用
			原理 0x的意思其实是十六进制,后面加的数其实就是一个十六进制数. 在十六进制中,我们知道a代表10,b代表11,c代表12,d代表13,e代表14,f代表15. 所以3f3f3f3f这个数用十进制数 ... 
- 2019牛客暑期多校训练营(第一场) - H - XOR - 线性基
			https://ac.nowcoder.com/acm/contest/881/H 题意: 给定n个整数,求其中异或和为 \(0\) 的子集的大小的和. 题解思路: 首先转化为每个可以通过异或表示 \ ... 
- 修改ps工具栏字体大小
			修改ps工具栏字体大小 先改电脑分辨率或者改首选项--界面---文字,退出后,重新打开,但你会发现问题还是没解决,我们接着往下 找到文件夹安装目录下的photoshops.exe启动文件(查找方法 ... 
- 金蝶KIS客户端修改IP连接服务器的方法
			问题现象:服务器IP变更后,金蝶KIS客户端打开时提示多个错误,并会自动关闭,无法联网登录 1. 到下面位置修改注册表 Windows Registry Editor Version 5.00 [HK ... 
- JDBC之Statement、PreparedStatement和CallableStatement
			JDBC提供了Statement.PreparedStatement和CallableStatement三种方式来执行查询语句,其中Statement用于通用查询,PreparedStatement用 ... 
- Linux双网卡绑定bond详解
			参考资料: 1.https://blog.csdn.net/shengerjianku/article/details/79221886 
- NIO摘录
			NIO,一种基于通道和缓冲区的I/O方式,可以使用native函数库直接分配堆外内存,然后通过一个存储在java 堆的DirectBteBuffer对象作为这块内存的引用进行操作,避免了再java堆和 ... 
- Flutter中的日期、格式化日期、日期选择器组件
			Flutter中的日期和时间戳 //獲取當前日期 DateTime _nowDate = DateTime.now(); print(_nowDate);//2019-10-29 10:57:20.3 ... 
