C、CSL 的密码 【set暴力 || 后缀数组】 (“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛 )
题目传送门:https://ac.nowcoder.com/acm/contest/551/C
题目描述
为了改变这一点,他决定重新设定一个密码。于是他随机生成了一个很长很长的字符串,并打算选择一个子串作为新密码。他认为安全的密码长度至少为 m,那么他有多少种不同选择方式呢?两种方案不同,当且仅当选出的密码内容不同。
输入描述:
- 第一行有两个整数 n 和 m ,分别表示 CSL 随机生成的字符串长度和安全的密码的最短长度。
输出描述:
- 在一行输出一个整数,表示 CSL 能选择的方案数。
备注:
- 除样例外,所有的测试数据的字符串的每个字符均从小写字母 a - z 等概率随机生成。
解题思路:
① 枚举长度不超过 10 的子串,用set去重。
为什么是长度不超过 10 呢?因为题目说明了是随机生成,“串中单个字符的选择有26种,串越短,碰撞概率越高,越长则串的可能性越多,碰撞概率很小”
(听说出题人为了让不会后缀数组的童鞋也能 A 这道题,特意搞成了随机),以后在字符串题目看见“随机”二字就要想办法莽一波了。
AC code:
- #include <bits/stdc++.h>
- #define INF 0x3f3f3f3f
- #define LL long long
- using namespace std;
- const int MAXN = 2e5+;
- int N, M;
- set<string>ans[MAXN];
- string str;
- string tp;
- int main()
- {
- scanf("%d %d", &N, &M);
- cin >> str;
- int len = min(N, );
- LL res = (LL)(N-M+)*(N-M+)/;
- for(int i = M; i <= len; i++){
- for(int j = ; j+i- < N; j++){
- tp = str.substr(j, i);
- if(ans[i].find(tp) != ans[i].end()){
- res--;
- }
- ans[i].insert(tp);
- }
- }
- printf("%lld\n", res);
- return ;
- }
② 用后缀数组,预处理出 sa 和 height 数组
不同子串的个数数是 n-sa[ k ] - height[ k ] (前提 sa[i] <= n-m, 因为要求子串长度至少为 m)
每个子串都是某个后缀的前缀, 对于一个后缀。 它将产生n - sa[k]个前缀
但是有height[k]个前缀是跟前一个字符串的前缀相同。
故每个后缀的贡献是n - sa[k] - height[k]
求和即可
但是这里会把 长度小于 m 的子串也加进来,所以特判一下如果 height[ k ] < m-1 ,则把小于 m 长度的子串数(m-1-height[ k ] ) 删掉即可。
AC code:
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <vector>
- #include <set>
- #include <queue>
- #include <algorithm>
- #define MAXN 555555
- #define MAXM 200
- #define INF 1000000000
- #define LL long long
- using namespace std;
- int r[MAXN];
- int wa[MAXN], wb[MAXN], wv[MAXN], tmp[MAXN];
- int sa[MAXN]; //index range 1~n value range 0~n-1
- int cmp(int *r, int a, int b, int l)
- {
- return r[a] == r[b] && r[a + l] == r[b + l];
- }
- void da(int *r, int *sa, int n, int m)
- {
- int i, j, p, *x = wa, *y = wb, *ws = tmp;
- for (i = ; i < m; i++) ws[i] = ;
- for (i = ; i < n; i++) ws[x[i] = r[i]]++;
- for (i = ; i < m; i++) ws[i] += ws[i - ];
- for (i = n - ; i >= ; i--) sa[--ws[x[i]]] = i;
- for (j = , p = ; p < n; j *= , m = p)
- {
- for (p = , i = n - j; i < n; i++) y[p++] = i;
- for (i = ; i < n; i++)
- if (sa[i] >= j) y[p++] = sa[i] - j;
- for (i = ; i < n; i++) wv[i] = x[y[i]];
- for (i = ; i < m; i++) ws[i] = ;
- for (i = ; i < n; i++) ws[wv[i]]++;
- for (i = ; i < m; i++) ws[i] += ws[i - ];
- for (i = n - ; i >= ; i--) sa[--ws[wv[i]]] = y[i];
- for (swap(x, y), p = , x[sa[]] = , i = ; i < n; i++)
- x[sa[i]] = cmp(y, sa[i - ], sa[i], j) ? p - : p++;
- }
- }
- int Rank[MAXN]; //index range 0~n-1 value range 1~n
- int height[MAXN]; //index from 1 (height[1] = 0)
- void calheight(int *r, int *sa, int n)
- {
- int i, j, k = ;
- for (i = ; i <= n; ++i) Rank[sa[i]] = i;
- for (i = ; i < n; height[Rank[i++]] = k)
- for (k ? k-- : , j = sa[Rank[i] - ]; r[i + k] == r[j + k]; ++k);
- return;
- }
- char s[MAXN];
- int main()
- {
- int lenn = , n = ;
- scanf("%d %d", &n, &lenn);
- scanf("%s", s);
- int m = ;
- for(int i = ; i < n; i++)
- {
- r[i] = (int)s[i];
- m = max(m, r[i]);
- }
- r[n] = ;
- da(r, sa, n + , m + );
- calheight(r, sa, n);
- long long ans = ;
- for(int i = ; i <= n; i++){
- if(sa[i] <= n-lenn){
- ans += n - sa[i] - height[i];
- if(height[i] < lenn-) ans-=(lenn--height[i]);
- }
- }
- printf("%lld\n", ans);
- return ;
- }
当然,正解还有AC自动机,不过本zZ太弱了,还在啃后缀数组。
一个队友打的AC自动机用了 一百多ms, 而我们打的后缀数组用了 18ms,暴力那个直接用了八百多ms...
C、CSL 的密码 【set暴力 || 后缀数组】 (“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛 )的更多相关文章
- H、CSL 的拼图 【多维点的交换】 (“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛)
题目传送门:https://ac.nowcoder.com/acm/contest/551/H 题目描述 众所周知 CSL 不仅玩魔方很强,打麻将也很强.今天他打魔法麻将的时候,在路上撞到了一个被打乱 ...
- G、CSL 的训练计划【BFS 贪心】(“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛)
题目传送门:https://ac.nowcoder.com/acm/contest/551/G 链接:https://ac.nowcoder.com/acm/contest/551/G来源:牛客网 题 ...
- F、CSL 的神奇序列 【规律】 (“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛)
题目传送门:https://ac.nowcoder.com/acm/contest/551/F 题目描述 CSL 有一个神奇的无穷实数序列,他的每一项满足如下关系: 对于任意的正整数 n ,有 n∑k ...
- E、CSL 的魔法 【模拟】 (“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛)
题目传送门:https://ac.nowcoder.com/acm/contest/551#question 题目描述 有两个长度为 n 的序列,a0,a1,…,an−1a0,a1,…,an−1和 b ...
- D、CSL 的字符串 【栈+贪心】 (“新智认知”杯上海高校程序设计竞赛暨第十七届上海大学程序设计春季联赛)
题目传送门:https://ac.nowcoder.com/acm/contest/551#question 题目描述 CSL 以前不会字符串算法,经过一年的训练,他还是不会……于是他打算向你求助. ...
- hdu4691 Front compression ——暴力 || 后缀数组
link:http://acm.hdu.edu.cn/showproblem.php?pid=4691 暴力,数据明显太水了吧,n=10^5, O(n^2)的复杂度哎喂.想让大家暴力写直接让n=100 ...
- BZOJ_2754__[SCOI2012]_喵星球上的点名_(暴力+后缀数组)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=2754 给出n个姓名串和m个点名串.求每个点名串在多少人的姓名中出现过(在名中出现或在姓中出现, ...
- “盛大游戏杯”第15届上海大学程序设计联赛夏季赛暨上海高校金马五校赛题解&&源码【A,水,B,水,C,水,D,快速幂,E,优先队列,F,暴力,G,贪心+排序,H,STL乱搞,I,尼姆博弈,J,差分dp,K,二分+排序,L,矩阵快速幂,M,线段树区间更新+Lazy思想,N,超级快速幂+扩展欧里几德,O,BFS】
黑白图像直方图 发布时间: 2017年7月9日 18:30 最后更新: 2017年7月10日 21:08 时间限制: 1000ms 内存限制: 128M 描述 在一个矩形的灰度图像上,每个 ...
- BZOJ.4516.[SDOI2016]生成魔咒(后缀数组 RMQ)
题目链接 后缀自动机做法见这(超好写啊). 后缀数组是可以做的: 本质不同的字符串的个数为 \(子串个数-\sum_{ht[i]}\),即 \(\frac{n(n+1)}{2}-\sum_{ht[i] ...
随机推荐
- 十三、curator recipes之SharedCounter
简介 我们可以通过curator实现对一个分布式环境下共享变量的访问,zookeeper将共享变量维护在同一个路径下. 官方文档:http://curator.apache.org/curator-r ...
- 您必须先调用“WebSecurity.InitializeDatabaseConnection”方法,然后再调用"WebSecurity"类的任何其他方法。
今天调试程序的时候出现了这个是,可惜没截图! 您必须先调用“WebSecurity.InitializeDatabaseConnection”方法,然后再调用"WebSecurity&quo ...
- 撩课-Web大前端每天5道面试题-Day14
1. 请写出至少5个html5新增的标签,并说明其语义和应用场景? section:定义文档中的一个章节; nav:定义只包含导航链接的章节; header:定义页面或章节的头部; 它经常包含 log ...
- SpringBoot之整合MyBatis
今天了解一下SpringBoot如何与我们最常用的ORM框架Mybatis整合. 一. 需要在pom.xml文件里加入mybatis的依赖 <dependency> <groupId ...
- springboot基本注解
声明Bean的注解: @Component组件 @Service service层 @Respository dao层 @Controller 注入Bean的注解: @Autowired Spring ...
- HDU2048 神,上帝以及老天爷 错排
http://acm.hdu.edu.cn/showproblem.php?pid=2048 这是一道错排的题目 错排如下:http://baike.baidu.com/link?url=U2_H-4 ...
- [转]Tips——Chrome DevTools - 25 Tips and Tricks
Chrome DevTools - 25 Tips and Tricks 原文地址:https://www.keycdn.com/blog/chrome-devtools 如何打开? 1.从浏览器菜单 ...
- js获取昨天/上周/上个月开始和结束的时间戳,可以设置时分秒 js obtain start and end timestamp of yesterday/last week/last month, with set of hour/minute/second
//obtain timestamp of last week var now=new Date() var nowDayOfWeek = now.getDay(); //今天本周的第几天 var n ...
- Linux命令行bash批量重命名文件
本文介绍下,在linux下使用shell批量重命名文件的例子,有需要的朋友参考下吧. 在linux中,重命名文件名,需要用到mv命令.如果需要批量重命名名一批文件,就需要写bash脚本或命令行了. 例 ...
- ajax的content-download时间过慢问题的解决与思考
其次,查看出现延迟问题的业务页面和不出现延迟的业务页面对这一组件的调用区别. 通过对比,也没有发现两个组件有何不同.(故这一奥秘,有兴趣的同学可以联系我一起讨论.....我可以把源码发给你) 经过多次 ...