模拟赛 sutoringu
sutoringu
题意:
询问有多少一个字符串内有多少个个子区间,满足可以分成k个相同的串。
分析:
首先可以枚举一个长度len,表示分成的k个长为len的串。然后从1开始,每len的长度分成一块,分成(n-1)/k+1块,首先可以求出连续的k块的是否是合法。
此时只求了起点是1+len*i的串,还有些起点在块内的没有求。
枚举k-1个相同的块,设这些块为i...j,j-i+1=k。然后与求一下第i块和第i-1块最长后缀,设为a,求一下第j块和第j+1块的最长前缀,设为b。说明如果起点在第i-1块的串,必须是后面a个字符,这些串的终点必须是第j+1块的前b个字符。于是计算一下。
如何求连续的k块是否是一样的?可以求出这连续k块在的rank,然后取一个最大的rank和一个最小的rank,然后求之间的height最小值即可。
复杂度$nlog^2n$。
代码:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#include<cctype>
#include<set>
#include<queue>
#include<vector>
#include<map>
#include<bitset>
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ;
char s[N];
int t1[N], t2[N], c[N], sa[N], rnk[N], ht[N], f[N][], Log[N];
void getsa(int n) {
int m = , i, *x = t1, *y = t2;
for (i = ; i <= m; ++i) c[i] = ;
for (i = ; i <= n; ++i) x[i] = s[i], c[x[i]] ++;
for (i = ; i <= m; ++i) c[i] += c[i - ];
for (i = n; i >= ; --i) sa[c[x[i]]--] = i;
for (int k = ; k <= n; k <<= ) {
int p = ;
for (i = n - k + ; i <= n; ++i) y[++p] = i;
for (i = ; i <= n; ++i) if (sa[i] > k) y[++p] = sa[i] - k;
for (i = ; i <= m; ++i) c[i] = ;
for (i = ; i <= n; ++i) c[x[y[i]]] ++;
for (i = ; i <= m; ++i) c[i] += c[i - ];
for (i = n; i >= ; --i) sa[c[x[y[i]]]--] = y[i];
swap(x, y);
p = ;
x[sa[]] = ;
for (i = ; i <= n; ++i)
x[sa[i]] = (y[sa[i]] == y[sa[i - ]] && y[sa[i] + k] == y[sa[i - ] + k]) ? p - : p ++;
if (p > n) break;
m = p;
}
for (i = ; i <= n; ++i) rnk[sa[i]] = i;
ht[] = ;
int k = ;
for (i = ; i <= n; ++i) {
if (rnk[i] == ) continue;
if (k) k --;
int j = sa[rnk[i] - ];
while (i + k <= n && j + k <= n && s[i + k] == s[j + k]) k ++;
ht[rnk[i]] = k;
}
for (i = ; i <= n; ++i) f[i][] = ht[i];
for (i = ; i <= n; ++i) Log[i] = Log[i >> ] + ;
for (int j = ; j <= Log[n]; ++j)
for (i = ; i + ( << j) - <= n; ++i)
f[i][j] = min(f[i][j - ], f[i + ( << (j - ))][j - ]);
}
int LCP(int i,int j) {
i = rnk[i], j = rnk[j];
if (i > j) swap(i, j);
i ++;
int k = Log[j - i + ];
return min(f[i][k], f[j - ( << k) + ][k]);
}
int LCP2(int i,int j) {
i ++;
int k = Log[j - i + ];
return min(f[i][k], f[j - ( << k) + ][k]);
} set<int> sk;
int n, k, rev[N]; bool check(int len) {
int l = *sk.begin();
set<int>::iterator it = sk.end(); it --;
int r = *it;
return LCP2(l, r) >= len;
}
int check2(int i,int j,int len) {
if (sk.size() >= && !check(len)) return ;
int a = min(len - , LCP(rev[i - ], rev[i - + len]));
if (j + len > n) return ;
int b = min(len - , LCP(j, j + len));
return max(, b - (len - a) + );
}
int main() {
freopen("sutoringu.in", "r", stdin);
freopen("sutoringu.out", "w", stdout);
n = read(), k = read();
scanf("%s", s + );
s[n + ] = '#';
for (int i = ; i <= n; ++i)
s[i + n + ] = s[n - i + ], rev[n - i + ] = i + n + ;
getsa(n + n + );
LL ans = ;
for (int len = ; len <= n; ++len) {
sk.clear();
for (int i = ; i <= n; i += len) {
sk.insert(rnk[i]);
if (sk.size() > k) sk.erase(rnk[i - len * k]);
if (sk.size() == k) ans += check(len);
}
if (len == ) continue;
sk.clear();
for (int i = len + ; i <= n; i += len) {
sk.insert(rnk[i]);
if (sk.size() > k - ) sk.erase(rnk[i - len * (k - )]);
if (sk.size() == k - ) ans += check2(i - (k - ) * len, i, len);
}
}
cout << ans;
return ;
}
模拟赛 sutoringu的更多相关文章
- 3.27模拟赛 sutoringu(后缀数组)
\(\color{white}{mjt是机房模拟赛独自切过题的唯一的人...}\) (应本人要求删掉惹) \(Description\) 给你\(n,k\)和长为\(n\)的字符串\(s\).一个区间 ...
- NOIP模拟赛20161022
NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...
- NOI模拟赛 Day1
[考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧 ...
- NOIP第7场模拟赛题解
NOIP模拟赛第7场题解: 题解见:http://www.cqoi.net:2012/JudgeOnline/problemset.php?page=13 题号为2221-2224. 1.car 边界 ...
- contesthunter暑假NOIP模拟赛第一场题解
contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...
- NOIP模拟赛 by hzwer
2015年10月04日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...
- 小奇模拟赛9.13 by hzwer
2015年9月13日NOIP模拟赛 by hzwer (这是小奇=> 小奇挖矿(explo) [题目背景] 小奇要开采一些矿物,它驾驶着一台带有钻头(初始能力值w)的飞船,按既定路线依次飞 ...
- PKUSC 模拟赛 day1 下午总结
下午到了机房之后又困又饿,还要被强行摁着看英文题,简直差评 第一题是NOIP模拟赛的原题,随便模拟就好啦 本人模拟功力太渣不小心打错了个变量,居然调了40多分钟QAQ #include<cstd ...
- [GRYZ]寒假模拟赛
写在前面 这是首次广饶一中的OIERS自编自导,自出自做(zuo)的模拟赛. 鉴于水平气压比较低,机(wei)智(suo)的WMY/XYD/HYXZC就上网FQ下海找了不少水(fei)题,经过他们优( ...
随机推荐
- 用例设计之API用例覆盖准则
基本原则 本文主要讨论API测试的用例/场景覆盖,基本原则如下: 用户场景闭环(从哪来到哪去) 遍历所有的实现逻辑路径 需求点覆盖 覆盖维度 API协议(参数&业务场景) 中间件检查 异常场景 ...
- 重学C语言---03数据和C
1.数据的必要性.数据使我们生活中不可缺少的东西,程序也是如次,离不开数据.将文字.图片和单词等输入到算计,将其展现出来或者做一系列操作等. 2.实例程序. /*rhodium.c--用金属铑衡量体重 ...
- Hibernate 二级缓存配置
详见:https://www.cnblogs.com/Junsept/p/7324981.html Hibernate的cache管理: Cache就是缓存,它往往是提高系统性能的最重要手段,对数据起 ...
- vscode 折叠所有区域代码的快捷键
折叠:ctrl + L ctrl + 0(主键盘区的0,不是小键盘区的0) 展开:ctrl + K ctrl + J 老是忘记,在此记录
- 为MySQ启用HugePage
8.12.4.2 Enabling Large Page Support Some hardware/operating system architectures support memory pag ...
- Windows用命令打开常用的设置页面和常用快捷键
Win+R输入以下内容来快捷打开常用设置 compmgmt.msc # 计算机管理 diskmgmt.msc # 磁盘管理 devmgmt.msc # 设备管理 services.msc # 服务管理 ...
- Skype 服务器客户端策略参数优化
1.skype通讯录原理 对于skype客户端的通讯录同步,首先说说原理,通讯簿信息是从AD同步的skype前端服务器(每天1:30),在从前端服务器同步的客户端(大概1小时内同步一次). skype ...
- PyQt5--QLineEdit
# -*- coding:utf-8 -*- ''' Created on Sep 20, 2018 @author: SaShuangYiBing Comment: ''' import sys f ...
- MySQL5.7通过压缩包方式安装与配置
首先下载MySQL5.7的压缩包:https://dev.mysql.com/downloads/mysql/5.7.html#downloads 1.解压缩到目标文件夹,解压后有许多文件,介绍一下用 ...
- 8、Django的模型层(2)
第3节:多表操作 3.1 创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作 ...