Description

  

  给你一个长度不超过100的字符串。一共进行\(N\)次操作,第\(i\)次操作是将当前字符串复制一份接到后面,并将新的一份循环移位\(k_i\)(\(1 \le k_i \le 100\))次。给出\(M\)(\(1 \le M \le 100000\))个询问,每次询问所有操作完成之后,\([l,r]\)中,某个字母出现了多少次。其中\(1 \le l \le r \le 10^{18}\)。

  

  

  

Solution

  

   我开场就写了2个小时的暴力分治,并惊喜地发现单个询问可以秒出。结果一组询问需要0.01s,拿到了40分的好成绩。

  

   首先\(N\)只有约前60项是有意义的,因此总操作数大约是60次。

  

   这种字符串变换题目要重点观察变换前和变换后是否有一大块一大块是相等的。比如某次操作前,字符串是\(S\),\(A\)和\(B\)是\(S\)的两块(即\(S=AB\))其中B的长度恰好是这次操作的偏移值。那么操作完之后,字符串的变化如下:

\[AB\rightarrow AB\;BA
\]

   既然只有60次操作,而每次操作的\(B\)的长度不超过100,我们完全可以算出每次操作的\(B\)串。即枚举每个字符,反向模拟这个字符是怎么从原串变换来的,即可在一个\(\log\)的时间确定每个字符是什么。

  

   将询问查分,则我们要求\([1,n]\)中有多少个\(c\)字符。

  

   考虑从最后一次操作开始递归向前计算(其实应该是:最早的一次操作,满足操作后串长不小于\(n\))。

  

   如果\(n\)落在左边的\(AB\)内:那么直接递归前一次操作,返回其答案。

  

   如果\(n\)落在右边的\(B\)内:左半边\(AB\)的答案显然,就是原串中这个字符的数量乘上左半边有多少个原串。对于右边部分,我们预处理出每次操作中\(B\)的字母前缀和,\(O(1)\)可询问\(B\)前缀字母数量。两者加起来就是答案。

  

   如果\(n\)落在右边的\(A\)内:\(ABB\)的答案可以用上一个情况的思路直接算,而最右边的\(A\)的答案,其实就是最左边的\(A\)的对应位置的答案。和第一种情况一样,我们递归前一次操作即可知道这部分的答案。

  

   我们发现总分治递归层数不会超过有效操作次数。因此这题可以在\(\mathcal O(M\log 10^{18})\)内解决。

  

  

  

Code

  

#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
namespace IO{
const int S=20000005;
char buffer[S];
int pos;
void Load(){
pos=0;
fread(buffer,1,S,stdin);
}
char getChar(){
char res=buffer[pos++];
if(pos>=S)
Load();
return res;
}
ll getLong(){
ll x=0,f=1;
char c=getChar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getChar();}
while('0'<=c&&c<='9'){x=x*10+c-'0';c=getChar();}
return x*f;
}
int getStr(char *str){
int len=0;
for(char c=getChar();'a'<=c&&c<='z';c=getChar())
str[len++]=c;
return len;
}
}
using IO::getLong;
using IO::getStr;
const int N=110,B=70,C=26;
const ll UP=2e18;
char str[N];
int slen;
int n,m,off[100005];
int pre[N][C],f[B][N][C];
void readData(){
slen=IO::getStr(str+1);
n=getLong(); m=getLong();
for(int i=1;i<=n;i++)
off[i]=getLong();
}
inline ll get_len(int bit){
return 1ll*slen*(1ll<<bit);
}
char get_char(int bit,ll x){
if(bit==0)
return str[x];
ll mid=get_len(bit-1);
if(x<=mid)
return get_char(bit-1,x);
ll cut=mid+off[bit];
if(x<=cut)
return get_char(bit-1,mid-(cut-x));
else
return get_char(bit-1,x-cut);
}
void precount(){
for(int i=1;i<=slen;i++){
for(int j=0;j<26;j++)
pre[i][j]=pre[i-1][j];
pre[i][str[i]-'a']++;
}
for(int i=1;get_len(i)<UP;i++){
ll mid=get_len(i-1);
off[i]%=mid;
for(int j=1;j<=off[i];j++){
for(int k=0;k<26;k++)
f[i][j][k]+=f[i][j-1][k];
char c=get_char(i-1,mid-off[i]+j);
f[i][j][c-'a']++;
}
}
}
ll solve(int bit,ll n,int c){
if(bit==0)
return pre[n][c];
ll mid=get_len(bit-1),cut=mid+off[bit];
if(n<=mid)
return solve(bit-1,n,c);
if(n<=cut)
return 1ll*pre[slen][c]*(1ll<<(bit-1))+f[bit][n-mid][c];
else
return 1ll*pre[slen][c]*(1ll<<(bit-1))+f[bit][cut-mid][c]+solve(bit-1,n-cut,c);
}
ll calc(ll n,char c){
if(!n)
return 0;
int bit;
for(bit=0;get_len(bit)<n;bit++);
return solve(bit,n,c-'a');
}
void answerQuery(){
ll l,r;
char c[2];
for(int i=1;i<=m;i++){
l=getLong(); r=getLong(); getStr(c);
printf("%lld\n",calc(r,c[0])-calc(l-1,c[0]));
}
}
int main(){
IO::Load();
readData();
precount();
answerQuery();
return 0;
}

CJB的大作的更多相关文章

  1. NOIp2018模拟赛三十五

    两道大数据结构把我砸懵 成绩:未提交 Orz xfz两道正解 A:[BZOJ4049][CREC2014B]mountainous landscape B:CJB的大作(CF改编题)

  2. 转载部长一篇大作:常用排序算法之JavaScript实现

    转载部长一篇大作:常用排序算法之JavaScript实现 注:本文是转载实验室同门王部长的大作,找实习找工作在即,本文颇有用处!原文出处:http://www.cnblogs.com/ywang172 ...

  3. cjb

    输入216.194.70.6 ,进入到是cjb.net的主页,并不是shell.cjb.net ,进入主页后点击shell,就进不去了 分析:shell.cjb.net被DNS污染了 解法:hosts ...

  4. Bishop的大作《模式识别与机器学习》Ready to read!

    久仰Bishop的大作“Pattern Recognition and Machine Learning”已久,在我的硬盘里已经驻扎一年有余,怎奈惧其页数浩瀚,始终未敢入手.近日看文献,屡屡引用之.不 ...

  5. 当今游戏大作share的特性大盘点

    极品游戏制作时的考虑要素大盘点 不知不觉入坑Steam已近4年,虽然说Steam的毒性让很多人走向一条不归路,但是想我这样即使"中毒"还是很快乐很感恩的.那么本期文章就谈谈我对其中 ...

  6. 深入Guerrilla Games解密次世代开山大作《杀戮地带暗影坠落》(The technology of Killzone Shadow Fall)

    文章摘要:这几天终于有时间,把全文翻译完了,自己感觉不是太满意,不过大家能看懂就好,就当一个学习的机会.整篇文章通过SONY第一方游戏工作室Guerrilla Games主创的语录,为我们展现了次世代 ...

  7. 关于Delphi中的字符串的浅析(瓢虫大作,里面有内存错误的举例)

    关于Delphi中的字符串的浅析 只是浅浅的解析下,让大家可以快速的理解字符串. 其中的所有代码均在Delphi7下测试通过. Delphi 4,5,6,7中有字符串类型包括了: 短字符串(Short ...

  8. 採訪The Molasses Flood:BioShock Infinite 游戏之后又一大作

    Xsolla有幸与Flame in the Flood游戏的开发人员之中的一个-----Forrest Dowling进行了採訪,Flame in the Flood这款非常棒的游戏在Kickstar ...

  9. 5月,专用程序猿的经典大作——APUE

    五一小长假刚刚过去,收回我们游走的心.開始你们的读书旅程吧! 本期特别推荐 经典UNIX著作最新版. 20多年来,这本书帮助几代程序猿写出强大.高性能.可靠的代码. 第3版依据当今主流系统进行更新,更 ...

随机推荐

  1. 20155218《网络对抗》Exp2 后门原理与实践

    20155218<网络对抗>Exp2 后门原理与实践 常用后门工具实践 1.Windows获得Linux Shell: 在Windows下,先使用ipconfig指令查看本机IP,使用nc ...

  2. Exp1 PC平台逆向破解(5)M

    Exp1 PC平台逆向破解(5)M [ 直接修改程序机器指令,改变程序执行流程] 用命令cp pwn1 20155320备份pwn1 输入objdump -d 20155320反汇编,找到call指令 ...

  3. 20155323刘威良 网络对抗 Exp2 后门原理与实践

    20155323 刘威良<网络攻防>Exp2后门原理与实践 实验内容 (1)使用netcat获取主机操作Shell,cron启动 (0.5分) (2)使用socat获取主机操作Shell, ...

  4. [GitHub]GitHub for Windows离线安装的方法

    这几天一直在尝试安装GitHub for windows ,安装程序是从https://windows.github.com/ 下载到的OneClick 部署程序,版本号为2.11.0.5.可能是因为 ...

  5. TMS320VC5509驱动LCD1602之奇怪问题和时序图

    1. 最近调试自己板子上LCD1602的时候,看下测试的时序图,因为下面的时序图导致LCD1602无法显示,下面的时序图是有问题的,E的上升沿和下降沿的时候,RW需要低电平 对比下淘宝上买的可以显示的 ...

  6. 文档对象类型DOM

    1 DOM概述 1.1 什么是DOM 文档对象模型 Document Object Model 文档对象模型 是表示和操作 HTML和XML文档内容的基础API 文档对象模型,是W3C组织推荐的处理可 ...

  7. 百度地图API的网页使用

    请看图示(以及参考官方文档): 图片尺寸:1710x822

  8. A1043 Is It a Binary Search Tree (25 分)

    A Binary Search Tree (BST) is recursively defined as a binary tree which has the following propertie ...

  9. UI Recorder 安装教程(二)

    前言: UI Recorder支持无线native app(Android, iOS)录制, 基于macaca实现:https://macacajs.com/ 本次教程只针对无线native app( ...

  10. PAT甲题题解-1059. Prime Factors (25)-素数筛选法

    用素数筛选法即可. 范围long int,其实大小范围和int一样,一开始以为是指long long,想这就麻烦了该怎么弄. 而现在其实就是int的范围,那难度档次就不一样了,瞬间变成水题一枚,因为i ...