Description

  

  如果某个串可以由两个一样的串前后连接得到,我们就称之为“偶串”。比如说“xyzxyz”和“aaaaaa”是偶串,而“ababab”和“xyzxy”则不是偶串。

  

​   对于一个非空串\(S\),我们定义\(f(S)\)是在\(S\)后面添加一些字符得到的最短偶串。比如\(f(\)'abaaba'\()=\)'abaababaab'。容易证明,对于一个非空串\(S\),\(f(S)\)是唯一的 。

  

​   现在给定一个由小写英文字母构成的偶串\(S\),你需要求出\(f^{10^{100}}(S)\),并统计计算结果的第\(l\)个字符到第\(r\)个字符中,每个字母出现了多少次 。

  

​   其中,\(f^{10^{100}}(S)\)是指\(f(f(f(...f(S)...)))\),式子中共有\(10^{100}\)个\(f\) 。

  

  

  

Solution

  

​   打表找规律。从整个串来寻找规律看不出什么,反而是分别考虑两半的变化比较有效。

  

​   我们称\(T\)为\(S\)的"Border",当且仅当\(S\)作为\(T\)的循环串的前缀出现,且\(T\)长度最小。

  

​   现有输入串\(SS\),令\(S\)的"Border"为\(T\),则会发现:

\[SS\rightarrow (ST)(ST)\rightarrow (STS)(STS)\rightarrow(STSST)(STSST)...
\]

​   由于操作次数过多,只考虑前半部分的变化,就能回答所有询问:

\[S\rightarrow ST\rightarrow STS\rightarrow STSST\rightarrow STSSTSTS
\]

​   我们发现,从第三个串开始,每一个串\(i\),都是由串\(i-1\)+串\(i-2\)得来。姑且称它们为\(\text{fib}\)串。

  

​   特别地:若\(|S|-|T|\)整除\(|S|\),则变化为

\[S\rightarrow ST\rightarrow STT\rightarrow STTT...
\]

​   特判掉这种情况。

  

​   记\(len_i\)为第\(i\)个\(\text{fib}\)串的长度,\(g_{i,j}\)为第\(i\)个\(\text{fib}\)串中\(j\)字符出现了多少次。由于\(\text{fib}\)在第85项左右就已经超出了\(1e18\),因此我们可以暴力计算出这两个数组。

  

​   对答案差分,假设要求\(1...r\)中,每个字符的出现次数。

  

​   有结论是,只要有\(len_{x_1}+len_{x_2}+...+len_{x_k}=r\),且\(len_{x_1}>len_{x_2}>...>len_{x_k}\),则\(1...r\)这个字符串就可以用\(x_1,x_2,...,x_k\)这\(k\)个\(\text{fib}\)串首尾相接得到。

  

​   所以对于询问我们从大到小枚举\(\text{fib}\)串累加每个字符的答案。最后可能会剩余一定长度无法消去,但剩余的长度一定不超过\(|S|\)(在\(\text{fib}\)串中甚至没有组成一个元素\(S\)),且是\(S\)的一个前缀,额外计算上这些部分即可。

  

​  

  

Code

  

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
const int N=200005;
int n,up,nex[N],type;
char str[N];
int pre[N][26];
ll l,r,cut,len[100],ans[26];
ll f[100][26];
void readData(){
scanf("%s%lld%lld",str+1,&l,&r);
n=strlen(str+1);
n>>=1;
for(int i=1;i<=n;i++){
for(int j=0;j<26;j++) pre[i][j]=pre[i-1][j];
pre[i][str[i]-'a']++;
}
}
void getNex(){
nex[1]=0;
for(int i=2,j;i<=n;i++){
j=nex[i-1];
while(j&&str[j+1]!=str[i]) j=nex[j];
nex[i]=(str[j+1]==str[i])?j+1:0;
}
}
void preWork(){
len[1]=n;
for(int i=1;i<=n;i++){
f[1][str[i]-'a']++;
f[2][str[i]-'a']++;
}
len[2]=n+cut;
for(int i=0;i<26;i++)
f[2][i]+=pre[cut][i];
for(int i=3;;i++){
for(int j=0;j<26;j++) f[i][j]=f[i-2][j]+f[i-1][j];
len[i]=len[i-2]+len[i-1];
if(len[i]>1e18){
up=i;
break;
}
}
}
void calc1(ll m,ll a){
if(m<=0) return;
ll t=m/cut;
for(int i=0;i<26;i++) ans[i]+=a*t*pre[cut][i];
t=m%cut;
for(int i=0;i<26;i++) ans[i]+=a*pre[t][i];
}
void calc2(ll m,ll a){
for(int i=up;i>=1;i--)
if(len[i]<=m){
m-=len[i];
for(int j=0;j<26;j++) ans[j]+=a*f[i][j];
}
for(int j=0;j<26;j++) ans[j]+=a*pre[m][j];
}
int main(){
readData();
getNex();
cut=n-nex[n];
if(n%cut==0){
calc1(r,1);
calc1(l-1,-1);
}
else{
preWork();
calc2(r,1);
calc2(l-1,-1);
}
for(int i=0;i<26;i++) printf("%lld ",ans[i]);
return 0;
}

【ARC077F】SS的更多相关文章

  1. 【ARC077F】SS kmp+打表找规律

    Description ​ 如果某个串可以由两个一样的串前后连接得到,我们就称之为"偶串".比如说"xyzxyz"和"aaaaaa"是偶串, ...

  2. 【arc077f】AtCoder Regular Contest 077 F - SS

    题意 给你一个形如"SS"的串S,以及一个函数\(f(x)\),\(x\)是一个形如"SS"的字符串,\(f(x)\)也是一个形如"SS"的 ...

  3. 【arc077f】AtCoder Regular Contest 074 F - Lotus Leaves

    题意 给定一个n*m的池塘,每个格子上可能有叶子. 从一个叶子出发,可以跳到相同行或相同列的叶子. 问至少去掉多少叶子,使得起点不能到达终点. \(n,m<=100\) 解法 很显然的最小割模型 ...

  4. 【转载】运维小技巧:使用ss命令代替 netstat

    转自:https://www.91ri.org/12470.html ss是Socket Statistics的缩写. 顾名思义,ss命令可以用来获取socket统计信息,它可以显示和netstat类 ...

  5. 一步步实现ABAP后台导入EXCEL到数据库【1】

    在SAP的应用当中,导入.导出EXCEL文件的情况是一个常见的需求,有时候用户需要将大量数据定期导入到SAP的数据库中.这种情况下,使用导入程序在前台导入可能要花费不少的时间,如果能安排导入程序为后台 ...

  6. 【Django】--Model字段

    参考地址:http://www.cnblogs.com/wupeiqi/articles/6216618.html 所有字段 AutoField(Field) --int自增列,必须填入参数prima ...

  7. 通用js函数集锦<来源于网络> 【二】

    通用js函数集锦<来源于网络> [二] 1.数组方法集2.cookie方法集3.url方法集4.正则表达式方法集5.字符串方法集6.加密方法集7.日期方法集8.浏览器检测方法集9.json ...

  8. 通用js函数集锦<来源于网络/自己> 【一】

    通用js函数集锦<来源于网络/自己>[一] 1.返回一个全地址2.cookie3.验证用户浏览器是否是微信浏览器4.验证用户浏览器是否是微博内置浏览器5.query string6.验证用 ...

  9. 【五】将博客从jekyll迁移到了hexo

    本系列有五篇:分别是  [一]Ubuntu14.04+Jekyll+Github Pages搭建静态博客:主要是安装方面  [二]jekyll 的使用 :主要是jekyll的配置  [三]Markdo ...

随机推荐

  1. L2 Helios OPcodez

    天堂2 Helios太阳神版本 的客户端和服务端封包 *********************** Client ***********************00 SendLogOut01 Req ...

  2. 学习python,第三篇:.pyc是个什么鬼?

    .pyc是个什么鬼? 1. Python是一门解释型语言? 我初学Python时,听到的关于Python的第一句话就是,Python是一门解释性语言,我就这样一直相信下去,直到发现了*.pyc文件的存 ...

  3. Netty源码分析第2章(NioEventLoop)---->第6节: 执行select操作

    Netty源码分析第二章: NioEventLoop   第六节: 执行select操作 分析完了selector的创建和优化的过程, 这一小节分析select相关操作 跟到跟到select操作的入口 ...

  4. Vue 列表渲染及条件渲染实战

    条件渲染 有时候我们要根据数据的情况,决定标签是否进行显示或者有其他动作.最常见的就是,表格渲染的时候,如果表格没有数据,就显示无数据.如果有数据就显示表格数据. Vue 帮我们提供了一个v-if的指 ...

  5. 第十二周作业_PSP总结报告

    回顾1 (1)回想一下你曾经对计算机专业的畅想 当初你是如何做出选择计算机专业的决定的?经过一个学期,你的看法改变了么,为什么? 你认为过去接触到的课程是否符合你对计算机专业的期待,为什么?经过一个学 ...

  6. 第33次Scrum会议(11/21)【欢迎来怼】

    一.小组信息 队名:欢迎来怼小组成员队长:田继平成员:李圆圆,葛美义,王伟东,姜珊,邵朔,阚博文 小组照片 二.开会信息 时间:2017/11/21 11:35~11:57,总计22min.地点:东北 ...

  7. TeamWork#3,Week5,Scrum Meeting 11.9

    由于经验不足和储备知识不够,最近我们的项目遇到了一些技术问题,需要对项目进行重新计划.我们总结了经验教训,找出了问题所在,明确了要补充的知识,加紧学习,将会在一周之内解决相关问题. 成员 已完成 待完 ...

  8. 团队博客作业Week4 --- 学霸网站--NABC

    1.需求(Need) 伴随着经济的发展,科学技术取得了飞速的发展,互联网在各行各业的发展中取得了广泛的应用.随着这些事物的发展,我们每个人都会接触到相当庞大的数据.如何在这些数据中找到自己需要的,如何 ...

  9. YQCB冲刺周第五天

    站立会议: 任务看板: 今天的任务为依旧为将用户记录的数据添加到数据库中,以及金额球的设置. 遇到的问题为金额球在jsp页面的显示.

  10. <s:action>的一些用法

    Action标签,顾名思义,是用来调用Action的标签,在JSP中页面中,可以具体指定某一命名空间中的某一Action.而标签的主体用于显示及渲染Actionr的处理结果. action标签有如下几 ...