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=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
}const int N = 600005;
char s[N];
int t1[N], t2[N], c[N], sa[N], rnk[N], ht[N], f[N][21], Log[N];
void getsa(int n) {int m = 130, i, *x = t1, *y = t2;for (i = 1; i <= m; ++i) c[i] = 0;for (i = 1; i <= n; ++i) x[i] = s[i], c[x[i]] ++;for (i = 1; i <= m; ++i) c[i] += c[i - 1];for (i = n; i >= 1; --i) sa[c[x[i]]--] = i;for (int k = 1; k <= n; k <<= 1) {int p = 0;for (i = n - k + 1; i <= n; ++i) y[++p] = i;for (i = 1; i <= n; ++i) if (sa[i] > k) y[++p] = sa[i] - k;for (i = 1; i <= m; ++i) c[i] = 0;for (i = 1; i <= n; ++i) c[x[y[i]]] ++;for (i = 1; i <= m; ++i) c[i] += c[i - 1];for (i = n; i >= 1; --i) sa[c[x[y[i]]]--] = y[i];swap(x, y);p = 2;x[sa[1]] = 1;for (i = 2; i <= n; ++i) x[sa[i]] = (y[sa[i]] == y[sa[i - 1]] && y[sa[i] + k] == y[sa[i - 1] + k]) ? p - 1 : p ++;if (p > n) break;m = p;}for (i = 1; i <= n; ++i) rnk[sa[i]] = i;ht[1] = 0;int k = 0;for (i = 1; i <= n; ++i) {if (rnk[i] == 1) continue;if (k) k --;int j = sa[rnk[i] - 1];while (i + k <= n && j + k <= n && s[i + k] == s[j + k]) k ++;ht[rnk[i]] = k;}for (i = 1; i <= n; ++i) f[i][0] = ht[i];for (i = 2; i <= n; ++i) Log[i] = Log[i >> 1] + 1;for (int j = 1; j <= Log[n]; ++j) for (i = 1; i + (1 << j) - 1 <= n; ++i) f[i][j] = min(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
}
int LCP(int i,int j) {i = rnk[i], j = rnk[j];if (i > j) swap(i, j);i ++;int k = Log[j - i + 1];return min(f[i][k], f[j - (1 << k) + 1][k]);
}
int LCP2(int i,int j) {i ++;int k = Log[j - i + 1];return min(f[i][k], f[j - (1 << k) + 1][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() >= 2 && !check(len)) return 0;int a = min(len - 1, LCP(rev[i - 1], rev[i - 1 + len]));if (j + len > n) return 0;int b = min(len - 1, LCP(j, j + len));return max(0, b - (len - a) + 1);
}
int main() {freopen("sutoringu.in", "r", stdin);freopen("sutoringu.out", "w", stdout);n = read(), k = read();scanf("%s", s + 1);s[n + 1] = '#';for (int i = 1; i <= n; ++i) s[i + n + 1] = s[n - i + 1], rev[n - i + 1] = i + n + 1;getsa(n + n + 1);LL ans = 0;for (int len = 1; len <= n; ++len) {sk.clear();for (int i = 1; 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 == 1) continue;sk.clear();for (int i = len + 1; i <= n; i += len) {sk.insert(rnk[i]);if (sk.size() > k - 1) sk.erase(rnk[i - len * (k - 1)]);if (sk.size() == k - 1) ans += check2(i - (k - 2) * len, i, len);}}cout << ans;return 0;
}

转载于:https://www.cnblogs.com/mjtcn/p/10610070.html

模拟赛 sutoringu相关推荐

  1. 3.27模拟赛 sutoringu(后缀数组)

    \(\color{white}{mjt是机房模拟赛独自切过题的唯一的人...}\) (应本人要求删掉惹) \(Description\) 给你\(n,k\)和长为\(n\)的字符串\(s\).一个区间 ...

  2. NOI.AC NOIP模拟赛 第六场 游记

    NOI.AC NOIP模拟赛 第六场 游记 queen 题目大意: 在一个\(n\times n(n\le10^5)\)的棋盘上,放有\(m(m\le10^5)\)个皇后,其中每一个皇后都可以向上.下 ...

  3. 2017.6.11 校内模拟赛

    题面及数据及std(有本人的也有原来的) :2017.6.11 校内模拟赛 T1 自己在纸上模拟一下后就会发现 可以用栈来搞一搞事情 受了上次zsq 讲的双栈排序的启发.. 具体就是将原盘子大小cop ...

  4. 2020年蓝桥杯模拟赛2020.3.25直播笔记

    2020年蓝桥杯模拟赛解题报告(CPP版本) 第八题 长草的bfs写法[我想暴力模拟O kmn] 深搜会爆 bfs像投到水里的涟漪 问题: const int dx[] = {1, 0, -1, 0} ...

  5. 2021年 第12届 蓝桥杯 第4次模拟赛真题详解及小结【Java版】

    蓝桥杯 Java B组 省赛决赛 真题详解及小结汇总[2013年(第4届)~2021年(第12届)] 第11届 蓝桥杯-第1.2次模拟(软件类)真题-(2020年3月.4月)-官方讲解视频 说明:大部 ...

  6. 2021年 第12届 蓝桥杯 第3次模拟赛真题详解及小结【Java版】

    蓝桥杯 Java B组 省赛决赛 真题详解及小结汇总[2013年(第4届)~2021年(第12届)] 第11届 蓝桥杯-第1.2次模拟(软件类)真题-(2020年3月.4月)-官方讲解视频 说明:大部 ...

  7. 蓝桥杯 Java B组 省赛决赛模拟赛 详解及小结汇总+题目下载【2013年(第4届)~2021年(第12届)】

    蓝桥杯 Java B组 省赛决赛模拟赛 详解及小结汇总+题目下载[2013年(第4届)~2021年(第12届)] 百度网盘-CSDN蓝桥杯资料(真题PDF+其它资料)   提取码:6666 2013年 ...

  8. 2020年 第11届 蓝桥杯 第2次模拟赛真题详解及小结【Java版】

    蓝桥杯 Java B组 省赛真题详解及小结汇总[2013年(第4届)~2020年(第11届)] 注意:部分代码及程序 源自 蓝桥杯 官网视频(历年真题解析) 郑未老师. 2013年 第04届 蓝桥杯 ...

  9. 10.30 NFLS-NOIP模拟赛 解题报告

    总结:今天去了NOIP模拟赛,其实是几道USACO的经典的题目,第一题和最后一题都有思路,第二题是我一开始写了个spfa,写了一半中途发现应该是矩阵乘法,然后没做完,然后就没有然后了!第二题的暴力都没 ...

最新文章

  1. linux的strace命令
  2. 程序员如果也能像C罗一样自律和勤奋,必将成为大神!
  3. 改革收入分配体制 网络电话成通信省钱先锋
  4. android webview javascript不执行,WebView中的JavaScript为什么不执行?
  5. Win11任务栏怎么隐藏
  6. GraphQL:现代数据库管理系统的演变
  7. Java MyBaties 映射配置文件 mapper
  8. docker image设置jdk版本_Docker 部署 Spring Boot
  9. SGX Architectural Encalve(AE)及SGX密钥
  10. 【专家推荐】保姆级开源工具推荐,一用一个爽,非常劲爆(收藏系列)
  11. 今日头条精准引流技巧,今日头条超简单的引流技巧
  12. weblogic启动错误 ClassNotFoundException: com.bea.wcp.sip.management.descriptor.beans.SipServerBean
  13. 制作PS合成在易拉罐中洗澡的水果
  14. 为什么要学习----------[澳大利亚]安德鲁·马修斯
  15. 卖出特斯拉、加仓百度背后的逻辑,ARK寻找下一个十倍股
  16. 【用户增长】用户增长方法论及增长思维
  17. Google Dapper学习
  18. rhinopython python编辑器、按钮编辑器、debug、rhinoscriptsyntax库函数使用手册
  19. Windows 远程桌面剪切板失效
  20. 部分华为手机解h265绿屏问题。

热门文章

  1. SSM整理笔记1——SSM网站初步功能设计
  2. 浏览器访问网页的详细内部过程
  3. 重操JS旧业第五弹:函数
  4. 添加毛玻璃的两中方法
  5. 转:谈谈Unicode编码,简要解释UCS、UTF、BMP、BOM等名词
  6. Flutter图像绘制原理深入分析
  7. 03 ansible核心模块 之 文件类型模块
  8. 货币市场基金的基本分类
  9. AOP——基于AspectJ的注解来实现AOP操作
  10. [算法]有趣算法合辑[21-30]