题意:给定一个字符串,问你它有多少个子串恰好出现 k 次。

析:后缀数组,先把height 数组处理出来,然后每次取 k 个进行分析,假设取的是 i ~ i+k-1,那么就有重复的,一个是 i-1 ~ i+k-1,另一个是 i ~ i+k,但是这样就删多了,再加上 i - 1 ~ i+k,这样就OK了。

代码如下:

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#include <assert.h>
#include <bitset>
#define debug() puts("++++");
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a, b, sizeof a)
#define sz size()
#define pu push_up
#define pd push_down
#define cl clear()
#define all 1,n,1
#define FOR(x,n) for(int i = (x); i < (n); ++i)
#define freopenr freopen("in.txt", "r", stdin)
#define freopenw freopen("out.txt", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const double inf = 1e20;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1e5 + 50;
const int mod = 1000;
const int dr[] = {-1, 0, 1, 0};
const int dc[] = {0, 1, 0, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
return r > 0 && r <= n && c > 0 && c <= m;
}
struct Array{
int s[maxn], sa[maxn], t[maxn], t2[maxn];
int h[maxn], r[maxn], c[maxn];
int n;
int dp[maxn][20]; void init(){ n = 0; memset(sa, 0, sizeof sa); }
void build_sa(int m){
int *x = t, *y = t2;
for(int i = 0; i < m; ++i) c[i] = 0;
for(int i = 0; i < n; ++i) ++c[x[i] = s[i]];
for(int i = 1; i < m; ++i) c[i] += c[i-1];
for(int i = n-1; i >= 0; --i) sa[--c[x[i]]] = i; for(int k = 1; k <= n; k <<= 1){
int p = 0;
for(int i = n-k; i < n; ++i) y[p++] = i;
for(int i = 0; i < n; ++i) if(sa[i] >= k) y[p++] = sa[i] - k;
for(int i = 0; i < m; ++i) c[i] = 0;
for(int i = 0; i < n; ++i) ++c[x[y[i]]];
for(int i = 1; i < m; ++i) c[i] += c[i-1];
for(int i = n-1; i >= 0; --i) sa[--c[x[y[i]]]] = y[i]; swap(x, y);
p = 1; x[sa[0]] = 0;
for(int i = 1; i < n; ++i)
x[sa[i]] = y[sa[i-1]] == y[sa[i]] && y[sa[i-1]+k] == y[sa[i]+k] ? p-1 : p++;
if(p >= n) break;
m = p;
}
} void getHight(){
int k = 0;
for(int i = 0; i < n; ++i) r[sa[i]] = i;
for(int i = 0; i < n; ++i){
if(k) --k;
int j = sa[r[i]-1];
while(s[i+k] == s[j+k]) ++k;
h[r[i]] = k;
}
} void rmq_init(){
for(int i = 1; i <= n; ++i) dp[i][0] = h[i];
for(int j = 1; (1<<j) <= n; ++j)
for(int i = 1; i + (1<<j) <= n; ++i)
dp[i][j] = min(dp[i][j-1], dp[i+(1<<j-1)][j-1]);
} int query(int L, int R){
if(L == R) return L;
++L;
int k = int(log(R-L+1) / log(2.0));
return min(dp[L][k], dp[R-(1<<k)+1][k]);
}
};
char s[maxn];
Array arr; int main(){
int T; cin >> T;
while(T--){
int k;
arr.init();
scanf("%d", &k);
scanf("%s", s);
for(int i = 0; s[i]; ++i)
arr.s[arr.n++] = s[i] - 'a' + 1;
arr.s[arr.n++] = 0;
arr.build_sa(28);
arr.getHight();
arr.rmq_init();
int ans = 0;
for(int i = 1; i < arr.n; ++i){
int l = i+k-1 < arr.n ? arr.query(i, i+k-1) : 0;
int x = i-1 > 0 && i+k-1 < arr.n ? arr.query(i-1, i+k-1) :0;
int y = i+k < arr.n ? arr.query(i, i+k) : 0;
int z = i-1 > 0 && i+k < arr.n ? arr.query(i-1, i+k) : 0;
ans += l - x - y + z;
}
printf("%d\n", ans);
}
return 0;
}

  

HDU 6194 string string string (后缀数组)的更多相关文章

  1. HDU5008 Boring String Problem(后缀数组 + 二分 + 线段树)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5008 Description In this problem, you are given ...

  2. HDU5853 Jong Hyok and String(二分 + 后缀数组)

    题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5853 Description Jong Hyok loves strings. One da ...

  3. CF1063F. String Journey(后缀数组+线段树)

    题目链接 https://codeforces.com/contest/1063/problem/F 题解 虽然本题有时间复杂度较高但非常好写的做法...... 首先,若答案为 \(k\),则一定存在 ...

  4. Codeforces 1063F - String Journey(后缀数组+线段树+dp)

    Codeforces 题面传送门 & 洛谷题面传送门 神仙题,做了我整整 2.5h,写篇题解纪念下逝去的中午 后排膜拜 1 年前就独立切掉此题的 ymx,我在 2021 年的第 5270 个小 ...

  5. hdu 4691 Front compression (后缀数组)

    hdu 4691 Front compression 题意:很简单的,就是给一个字符串,然后给出n个区间,输出两个ans,一个是所有区间的长度和,另一个是区间i跟区间i-1的最长公共前缀的长度的数值的 ...

  6. HDU 3518 Boring counting(后缀数组,字符处理)

    题目 参考自:http://blog.sina.com.cn/s/blog_64675f540100k9el.html 题目描述: 找出一个字符串中至少重复出现两次的字串的个数(重复出现时不能重叠). ...

  7. HDU 4691 Front compression(后缀数组)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4691 题意:给出Input,求出Compressed output.输出各用多少字节. 思路:求后缀数 ...

  8. hdu 1403 Longest Common Substring 后缀数组 模板题

    题目链接 题意 问两个字符串的最长公共子串. 思路 加一个特殊字符然后拼接起来,求得后缀数组与\(height\)数组.扫描一遍即得答案,注意判断起始点是否分别在两个串内. Code #include ...

  9. HDU - 4552 怪盗基德的挑战书 (后缀数组)

    Description "在树最漂亮的那天,当时间老人再次把大钟平均分开时,我会降临在灯火之城的金字塔前.带走那最珍贵的笑容."这是怪盗基德盗取巴黎卢浮宫的<蒙娜丽莎的微笑& ...

  10. HDU 1403-Longest Common Substring (后缀数组)

    Description Given two strings, you have to tell the length of the Longest Common Substring of them. ...

随机推荐

  1. 【学习笔记】LCT link cut tree

    大概就是供自己复习的吧 1. 细节讲解 安利两篇blog: Menci 非常好的讲解与题单 2.模板 把 $ rev $ 和 $ pushdown $ 的位置记清 #define lc son[x][ ...

  2. 简单租房子实例详解---(session、ajax、json前后台数据处理、分页)

    本次实例我们结合session.ajax.json前后台数据处理.分页技术做一个租房信息系统 一共有五个界面:包括 管理员和用户的登录界面 登录界面的后台 <?php session_start ...

  3. 关于v$BH

    关于v$bh的相关字段值FILE# NUMBER Datafile identifier number (to find the filename, query DBA_DATA_FILES or V ...

  4. CentOS7.6安装Maven

    官网下载地址:http://maven.apache.org/download.cgi 第一步:软件下载安装 进行安装目录:cd /opt/software (如果目录不存在,请先创建目录) 下载二进 ...

  5. from 动态显示select数据

    一. ModelChoiceField(ChoiceField)     ...                        django.forms.models.ModelChoiceField ...

  6. jquery UI 的 datapicker 中文汉化问题

    这个问题自己上网上百度的了很多的方法都没有 具体一点的东西,好在自己没有放弃 从昨天到现在,自己 摸索了很久终于找到了汉化的方法了,希望可以帮助到像我这样刚入web门的小白. 废话不说了直接来干货吧! ...

  7. objective-C中的"非正式协议"和“正式协议”

    objective-C中的接口与泛型 先承认我是标题党,因为在obj-c的世界中,官方根本没有"接口"与"泛型"这样的说法. 不过在obj-c中有二个与之接近的 ...

  8. 从零玩转JavaWeb系列7web服务器-----表单的提交

    在企业开放中如何提交一张表单? 例如:用户注册表 <!--表单内容--> <form action="/28-mystore/regist" id="R ...

  9. MongoDB常用增删改查语句

    数据库database 创建及查看库 1.有则使用这个数据库,没有就创建 use DATABASE_NAME 2. 查看当前选择的数据库,默认是test db 3.查看数据库,默认有admin.loc ...

  10. 封装basedao

    package com.huawei.common; import java.sql.ResultSet;import java.sql.SQLException; public interface ...