题目

分析

我们发现当两个字符串合并时,a0a1表示左右两个字符串中有多少个TC表示合并处新增的T的个数,那么

a0=a1

a1=a0+a1+C

s0s1表示左右手两个字符串,那么每一次操作后左右手字符串分别为:

操作次数  	    	 左手  右手
0 s0 s1
1 s1 s0s1
2 s0s1 s1s0s1
3 s1s0s1 s0s1s1s0s1
4 s0s1s1s0s1 s1s0s1s0s1s1s0s1
5 s1s0s1s0s1s1s0s1 s0s1s1s0s1s1s0s1s0s1s1s0s1
···

然后我们发现,从第1次操作以后,每次合并处是以s1s1s1s0为一个循环。也就是说当|s0|>=m-1时,我们用KMP处理出a0a1以及s1s1s1s0合并时新增T的个数,然后O(N)递推一遍就可以了。

但是n<=10^9,只能拿60分。

因为递推时有循环,所以就可以构造矩阵,打个矩阵快速幂O(logN)。

#include <cmath>
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <queue>
const long long maxlongint=2147483647;
using namespace std;
char s[30000],s1[30000],s2[30000],t[30000];
long long n,m,tot,ans,mo,next[30000],f[2][5],lens=1,lens1=1,nn,nnn;
long long jz[5][5]=
{
{0,0,0,0,0},
{0,1,1,0,0},
{0,1,2,0,0},
{0,1,1,1,0},
{0,0,1,0,1}
},b[5][5];
long long getnext()
{
long long i,j,k;
j=0;
for(i=2;i<=m;i++)
{
while(j>0 && t[j+1]!=t[i]) j=next[j];
if(t[j+1]==t[i]) j++;
next[i]=j;
}
}
long long kmp()
{
long long i,j,k;
getnext();
j=0;
for(i=1;i<=lens;i++)
{
while(j>0 && t[j+1]!=s[i]) j=next[j];
if(t[j+1]==s[i]) j++;
if(j==m) f[0][1]++;
}
j=0;
for(i=1;i<=lens1;i++)
{
while(j>0 && t[j+1]!=s1[i]) j=next[j];
if(t[j+1]==s1[i]) j++;
if(j==m) f[0][2]++;
}
}
long long kmp1()
{
long long i,j,k;
k=0;
for(i=lens-m+2;i<=lens;i++)
s2[++k]=s[i];
for(i=1;i<=m-1;i++)
s2[++k]=s1[i];
j=0;
for(i=1;i<=m+m-2;i++)
{
while(j>0 && t[j+1]!=s2[i]) j=next[j];
if(t[j+1]==s2[i]) j++;
if(j==m) f[0][0]++;
}
k=0;
for(i=lens1-m+2;i<=lens1;i++)
s2[++k]=s1[i];
for(i=1;i<=m-1;i++)
s2[++k]=s[i];
j=0;
for(i=1;i<=m+m-2;i++)
{
while(j>0 && t[j+1]!=s2[i]) j=next[j];
if(t[j+1]==s2[i]) j++;
if(j==m) f[0][3]++;
}
k=0;
for(i=lens1-m+2;i<=lens1;i++)
s2[++k]=s1[i];
for(i=1;i<=m-1;i++)
s2[++k]=s1[i];
j=0;
for(i=1;i<=m+m-2;i++)
{
while(j>0 && t[j+1]!=s2[i]) j=next[j];
if(t[j+1]==s2[i]) j++;
if(j==m) f[0][4]++;
}
}
long long mi()
{
long long x=0,y=1,i,j,k;
while(nn>0)
{
if(nn&1==1)
{
for(i=1;i<=4;i++)
{
f[x][i]=0;
for(j=1;j<=4;j++)
f[x][i]=(f[x][i]+(f[y][j]*jz[j][i])%mo)%mo;
}
x=y;
y=1-y;
}
for(i=1;i<=4;i++)
for(j=1;j<=4;j++)
{
b[i][j]=0;
for(k=1;k<=4;k++)
{
b[i][j]=(b[i][j]+(jz[i][k]*jz[k][j])%mo)%mo;
}
}
for(i=1;i<=4;i++)
for(j=1;j<=4;j++)
{
jz[i][j]=b[i][j];
}
nn/=2;
}
return y;
}
int main()
{
scanf("%d%d%d",&n,&m,&mo);
scanf("%s",t+1);
s[1]='0';
s1[1]='1';
long long i,j,k,l,x,y;
for(j=1;j<=n;j++)
{
for(i=1;i<=lens1;i++)
s2[i]=s1[i];
for(i=1;i<=lens;i++)
s1[i]=s[i];
for(i=1;i<=lens1;i++)
{
s1[lens+i]=s2[i];
}
for(i=1;i<=lens1;i++)
s[i]=s2[i];
x=lens1;
lens1+=lens;
lens=x;
y=j;
if(lens>=m)
break;
}
kmp();
if(n==y)
{
printf("%d\n",f[0][1]%mo);
return 0;
}
kmp1();
f[1][1]=(f[0][2])%mo;
f[1][2]=(f[0][1]+f[0][2]+f[0][0])%mo;
f[1][3]=(f[0][3])%mo;
f[1][4]=(f[0][4])%mo;
n-=y+1;
x=1;
y=0;
y=f[1][3];
n-=0;
nnn=n%2;
nn=n/2;
x=mi();
if(nnn==1)
{
printf("%d\n",(f[x][2])%mo);
return 0;
}
else
printf("%d\n",f[x][1]%mo);
}

【GDOI2016模拟3.9】暴走的图灵机的更多相关文章

  1. 【GDOI2016模拟3.15】基因合成(回文串+性质+DP)

    [GDOI2016模拟3.15]基因合成 题意: 给一个目标串,要求从空串进行最少的操作次数变成目标串,操作有两种: 在串的头或尾加入一个字符. 把串复制一遍后反向接到串的末尾. 因为有回文操作,所以 ...

  2. 【GDOI2016模拟3.16】幂(容斥 + 模型复杂转化)

    [GDOI2016模拟3.16]幂 \(X\in[1,A],Y\in[1,B]\),问:\(x^y\)的不用取值个数. \(A,B\)都是\(10^9\)级别. 然后我们开搞. 首先,假设一个合法的\ ...

  3. 【GDOI2016模拟4.22】总结

    前言 早上,一进机房,发现所有人神情严肃,一股(\(da\))(\(ba\))场的气氛迎面扑来,我一下子意识到:nothing good! 这场比赛结果不是很好,50分: 第一题:感觉上是个神奇的匹配 ...

  4. 【GDOI2016模拟3.10】习用之语

    前言 这道题看上去很水,结果我在比赛上浪费了N多时间在上面,但还是没AC.比赛结束后发现:实际上这道题还是是大水. 题目 分析 设字符串c1c2c3c4,其中c1.c2.c3.c4={'0'~'9', ...

  5. 【JZOJ4461】【GDOI2016模拟4.21】灯塔 分治

    题面 GDOI是一个地处丘陵的小国,为了边防建设,国王希望在国界线上的某一座山峰上建立一座灯塔,照亮整个边界.而灯塔建设的调研工作,就交给了你. GDOI的国境线上有N座连续的山峰,其中第i座的高度是 ...

  6. AI数学基础之:确定图灵机和非确定图灵机

    目录 简介 图灵机 图灵机的缺点 等效图灵机 确定图灵机 非确定图灵机 简介 图灵机是由艾伦·麦席森·图灵在1936年描述的一种抽象机器,它是人们使用纸笔进行数学运算的过程的抽象,它肯定了计算机实现的 ...

  7. 操作系统之CPU管理的直观想法

    计算机:是工具,帮助解决实际问题 操作系统,是为了方便使用硬件 计算机模型: 图灵机,模拟人类计算 起初的图灵机就像一个只会做一道菜的厨师 通用图灵机,核心是设置控制器动作(修改控制器),把逻辑读入控 ...

  8. p,np,npc,np难问题,确定图灵机与非确定图灵机

    本文转自豆瓣_燃烧的影子 图灵机与可计算性 图灵(1912~1954)出生于英国伦敦,19岁进入剑桥皇家学院研究量子力学和数理逻辑.1935年,图灵写出了"论高斯误差函数"的论文, ...

  9. 图灵机(转自wiki)

    图灵机(英语:Turing machine),又称确定型图灵机,是英国数学家艾伦·图灵于1936年提出的一种抽象计算模型,其更抽象的意义为一种数学逻辑机,可以看作等价于任何有限逻辑数学过程的终极强大逻 ...

随机推荐

  1. spring中的增强类型

    在spring中有两种增强方式:XML配置文件和注解配置.下面一次为大家讲解. 使用的是Aspectj第三方框架 纯POJO (在XML中配置节点) 使用@AspectJ,首先要保证所用的JDK 是5 ...

  2. 三:flask-配置文件的两种方式

    项目中,配置的参数一般采用配置文件的形式,方便统一管理 第一种方式:模块的形式:使用app.config.from_object(config)的方式加载配置文件,此方式需要导入配置文件视为模块 第二 ...

  3. springmvc中获取request对象,加载biz(service)的方法

    获取request对象: 首先配置web.xml文件--> <listener> <listener-class> org.springframework.web.con ...

  4. Mysql数据库存储数据时间与系统获取时间不一致

    最近进行项目开发,发现存在数据库内的数据和系统查询到的数据相差8小时 发现有2种比较合适的方法 (一)修改mysql服务的区时 centos进入mysql查看/修改时区 1.输入以下命令进入mysql ...

  5. 【Linux开发】CCS远程调试ARM,AM4378

    注意一点:CCS也是安装在Linux主机上的,不是安装在Windows上的,我在Windows上做出了很多尝试,但最终也不没明白究竟要用怎样的格式去执行在ARM-Linux应用程序,out文件ELF可 ...

  6. linux 系统目录权限

    小结: 目录的读.写.执行权限 1. 可读r:表示具有浏览目录 下面文件及子目录的权限 ls dir 1)如果没有x权限,则不能进到目录,既无法执行cd dir 2)如果没有x权限,ls列表时可以看到 ...

  7. python面试题--初级(二)

    基础不牢,地动山摇,面试的时候经常会被问到一些平时基础的很容易被忽视的知识点,所以重在积累,多看多背深入理解,才能在某一天工作中豁然开朗恍然大悟. 面试题不仅仅为了应付面试,更是知识点的一个梳理总结归 ...

  8. SpringBoot项目快速启动停止脚本

    SpringBoot项目快速启动停止脚本 1.在jar包同级目录下,创建 app.sh #!/bin/bash appName=`ls|grep .jar$` if [ -z $appName ] t ...

  9. kubernetes(k8s)容器编排工具基础概念

    Kubernetes (K8s): 中文社区:https://www.kubernetes.org.cn/replication-controller-kubernetes 官网:https://ku ...

  10. if练习

    练习: 1.简述变量命名规范 1.变量名由字母.下划线.数字组成 2.变量名不能以数字开头 3.变量不能使用python中的关键字 4.变量不能使用中文和拼音 5.区分大小写 6.变量名要具有描述性 ...