[Codechef CHSTR] Chef and String - 后缀数组
[Codechef CHSTR] Chef and String
Description
每次询问 \(S\) 的子串中,选出 \(k\) 个相同子串的方案有多少种。
Solution
本题要求不是很高,\(O(n^2)\) 统计每个出现次数子串个数即可。
我因为一个lld WA了一晚上(猛然意识到要%d读入long long的时候,之前一直没有翻车的原因是开了全局,如果是局部又不初始化就瞬间gg了,然鹅这个错误本地查不出来)
#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,q,m=256,sa[200005],y[200005],u[200005],v[200005],o[200005],r[200005],h[200005],T;
int buf[200005],answer[200005];
char str[200005];
int C[5005][5005];
const int modulo = 1e+9+7;
signed main()
{
C[0][0]=1;
for(int i=1;i<=5000;i++)
{
C[i][0]=1;
for(int j=1;j<=i;j++)
{
C[i][j]=(C[i-1][j]+C[i-1][j-1])%modulo;
}
}
scanf("%lld",&T);
while(T--)
{
memset(sa,0,sizeof sa);
memset(y,0,sizeof y);
memset(u,0,sizeof u);
memset(v,0,sizeof v);
memset(o,0,sizeof o);
memset(r,0,sizeof r);
memset(h,0,sizeof h);
memset(buf,0,sizeof buf);
memset(answer,0,sizeof answer);
memset(str,0,sizeof str);
scanf("%lld%lld",&n,&q);
scanf("%s",str+1);
for(int i=1; i<=n; i++) u[str[i]]++;
for(int i=1; i<=m; i++) u[i]+=u[i-1];
for(int i=n; i>=1; i--) sa[u[str[i]]--]=i;
r[sa[1]]=1;
for(int i=2; i<=n; i++) r[sa[i]]=r[sa[i-1]]+(str[sa[i]]!=str[sa[i-1]]);
for(int l=1; r[sa[n]]<n; l<<=1)
{
memset(u,0,sizeof u);
memset(v,0,sizeof v);
memcpy(o,r,sizeof r);
for(int i=1; i<=n; i++) u[r[i]]++, v[r[i+l]]++;
for(int i=1; i<=n; i++) u[i]+=u[i-1], v[i]+=v[i-1];
for(int i=n; i>=1; i--) y[v[r[i+l]]--]=i;
for(int i=n; i>=1; i--) sa[u[r[y[i]]]--]=y[i];
r[sa[1]]=1;
for(int i=2; i<=n; i++) r[sa[i]]=r[sa[i-1]]+((o[sa[i]]!=o[sa[i-1]])||(o[sa[i]+l]!=o[sa[i-1]+l]));
}
{
int i,j,k=0;
for(int i=1; i<=n; h[r[i++]]=k)
for(k?k--:0,j=sa[r[i]-1]; str[i+k]==str[j+k]; k++);
}
buf[1]=n*(n+1ll)/2ll;
for(int i=1; i<=n; i++) buf[1]-=h[i];
for(int i=1; i<=n; i++)
{
int l=h[i],r=h[i+1];
if(l<r)
{
++l;
for(int j=i+1; j<=n+1 && l<=r; j++)
{
while(r>h[j]&&l<=r)
{
buf[j-i]++;
--r;
}
}
}
}
for(int i=2;i<=n;i++) buf[1] -= buf[i];
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
(answer[i]+=(C[j][i]*buf[j])%modulo) %= modulo;
}
}
//for(int i=1;i<=n;i++) cout<<buf[i]<<" ";
//cout<<endl;1
for(int i=1;i<=q;i++)
{
int tmp;
scanf("%lld",&tmp);
if(tmp<=n) printf("%lld\n",answer[tmp]);
else printf("0\n");
}
}
}
[Codechef CHSTR] Chef and String - 后缀数组的更多相关文章
- hdu 3553 Just a String (后缀数组)
hdu 3553 Just a String (后缀数组) 题意:很简单,问一个字符串的第k大的子串是谁. 解题思路:后缀数组.先预处理一遍,把能算的都算出来.将后缀按sa排序,假如我们知道答案在那个 ...
- hdu 6194 沈阳网络赛--string string string(后缀数组)
题目链接 Problem Description Uncle Mao is a wonderful ACMER. One day he met an easy problem, but Uncle M ...
- HDU 6194 string string string (后缀数组)
题意:给定一个字符串,问你它有多少个子串恰好出现 k 次. 析:后缀数组,先把height 数组处理出来,然后每次取 k 个进行分析,假设取的是 i ~ i+k-1,那么就有重复的,一个是 i-1 ~ ...
- Hackerrank--Ashton and String(后缀数组)
题目链接 Ashton appeared for a job interview and is asked the following question. Arrange all the distin ...
- POJ3729 Facer’s string 后缀数组
Fa ...
- hdu 5030 Rabbit's String(后缀数组&二分法)
Rabbit's String Time Limit: 40000/20000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...
- hdu-6194 string string string 后缀数组 出现恰好K次的串的数量
最少出现K次我们可以用Height数组的lcp来得出,而恰好出现K次,我们只要除去最少出现K+1次的lcp即可. #include <cstdio> #include <cstrin ...
- [Codechef TASTR] Level of Difference - 后缀数组,容斥原理
[Codechef TASTR] Level of Difference Description 给定两个字符串,求恰好在一个字符串中出现过的本质不同的子串数量. Solution 设 \(U(S)\ ...
- HDU5008 Boring String Problem(后缀数组 + 二分 + 线段树)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5008 Description In this problem, you are given ...
随机推荐
- RHEL6 yum本地源配置
RHEL6 yum本地源配置 将RHEL6 的iso上传到/file1/xxx 新建目录/file1/xxx/mnt,将iso挂载到mnt目录 mount rhel-server-6.3-x86_64 ...
- tomcat - 解决 org.bouncycastle.asn1.ASN1Boolean 非法循环依赖的错误
背景 记录遇到一次奇怪的错误,在发布war包到Tomcat的时候,出现了org.bouncycastle.asn1.ASN1Boolean非法循环依赖的错误. INFO: Deploying web ...
- 【46】谷歌 Inception 网络简介Inception(2)
Inception 网络(Inception network) 在上节笔记中,你已经见到了所有的Inception网络基础模块.在本节笔记中,我们将学习如何将这些模块组合起来,构筑你自己的Incept ...
- Selenium实战(四)——unittest单元测试2(断言方法+discover()多测试用例的执行)
一.断言方法 方法 检查 版本 assertEqual(a,b) a==b assertNotEqual(a,b) a!=b assertTrue(x) bool(x) is True a ...
- Win10的Cortana小娜反应慢?试试这个方法
https://www.ithome.com/html/win10/158466.htm Win10语音助手Cortana小娜可以为用户提供全面的搜索服务,不管是本地还是在线,都可以轻松找到结果.不过 ...
- (转)jvm具体gc算法介绍标记整理--标记清除算法
转自:https://www.cnblogs.com/ityouknow/p/5614961.html GC算法 垃圾收集器 概述 垃圾收集 Garbage Collection 通常被称为“GC”, ...
- POJ 2431 Expedition 贪心 优先级队列
Expedition Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 30702 Accepted: 8457 Descr ...
- Python、Django、Celery中文文档分享
1.Python:链接:https://pan.baidu.com/s/12uzxbI-nMkpF7aMa966bTQ 密码:i1x9 2.Django:链接:https://pan.baidu.co ...
- gulp常用插件之autoprefixer使用
更多gulp常用插件使用请访问:gulp常用插件汇总 autoprefixer这是一款自动管理浏览器前缀的插件,它可以解析CSS文件并且添加浏览器前缀到CSS内容里. 更多使用文档请点击访问autop ...
- .NetCore学习笔记:一、UnitOfWork工作单元
Maintains a list of objects affected by a business transaction and coordinates the writing out of ch ...