【GDOI2016模拟3.9】暴走的图灵机
题目
分析
我们发现当两个字符串合并时,a0、a1表示左右两个字符串中有多少个T,C表示合并处新增的T的个数,那么
a0=a1
a1=a0+a1+C
令s0和s1表示左右手两个字符串,那么每一次操作后左右手字符串分别为:
操作次数 左手 右手
0 s0 s1
1 s1 s0s1
2 s0s1 s1s0s1
3 s1s0s1 s0s1s1s0s1
4 s0s1s1s0s1 s1s0s1s0s1s1s0s1
5 s1s0s1s0s1s1s0s1 s0s1s1s0s1s1s0s1s0s1s1s0s1
···
然后我们发现,从第1次操作以后,每次合并处是以s1s1和s1s0为一个循环。也就是说当|s0|>=m-1时,我们用KMP处理出a0、a1以及s1s1和s1s0合并时新增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】暴走的图灵机的更多相关文章
- 【GDOI2016模拟3.15】基因合成(回文串+性质+DP)
[GDOI2016模拟3.15]基因合成 题意: 给一个目标串,要求从空串进行最少的操作次数变成目标串,操作有两种: 在串的头或尾加入一个字符. 把串复制一遍后反向接到串的末尾. 因为有回文操作,所以 ...
- 【GDOI2016模拟3.16】幂(容斥 + 模型复杂转化)
[GDOI2016模拟3.16]幂 \(X\in[1,A],Y\in[1,B]\),问:\(x^y\)的不用取值个数. \(A,B\)都是\(10^9\)级别. 然后我们开搞. 首先,假设一个合法的\ ...
- 【GDOI2016模拟4.22】总结
前言 早上,一进机房,发现所有人神情严肃,一股(\(da\))(\(ba\))场的气氛迎面扑来,我一下子意识到:nothing good! 这场比赛结果不是很好,50分: 第一题:感觉上是个神奇的匹配 ...
- 【GDOI2016模拟3.10】习用之语
前言 这道题看上去很水,结果我在比赛上浪费了N多时间在上面,但还是没AC.比赛结束后发现:实际上这道题还是是大水. 题目 分析 设字符串c1c2c3c4,其中c1.c2.c3.c4={'0'~'9', ...
- 【JZOJ4461】【GDOI2016模拟4.21】灯塔 分治
题面 GDOI是一个地处丘陵的小国,为了边防建设,国王希望在国界线上的某一座山峰上建立一座灯塔,照亮整个边界.而灯塔建设的调研工作,就交给了你. GDOI的国境线上有N座连续的山峰,其中第i座的高度是 ...
- AI数学基础之:确定图灵机和非确定图灵机
目录 简介 图灵机 图灵机的缺点 等效图灵机 确定图灵机 非确定图灵机 简介 图灵机是由艾伦·麦席森·图灵在1936年描述的一种抽象机器,它是人们使用纸笔进行数学运算的过程的抽象,它肯定了计算机实现的 ...
- 操作系统之CPU管理的直观想法
计算机:是工具,帮助解决实际问题 操作系统,是为了方便使用硬件 计算机模型: 图灵机,模拟人类计算 起初的图灵机就像一个只会做一道菜的厨师 通用图灵机,核心是设置控制器动作(修改控制器),把逻辑读入控 ...
- p,np,npc,np难问题,确定图灵机与非确定图灵机
本文转自豆瓣_燃烧的影子 图灵机与可计算性 图灵(1912~1954)出生于英国伦敦,19岁进入剑桥皇家学院研究量子力学和数理逻辑.1935年,图灵写出了"论高斯误差函数"的论文, ...
- 图灵机(转自wiki)
图灵机(英语:Turing machine),又称确定型图灵机,是英国数学家艾伦·图灵于1936年提出的一种抽象计算模型,其更抽象的意义为一种数学逻辑机,可以看作等价于任何有限逻辑数学过程的终极强大逻 ...
随机推荐
- spring hibernate 事务整合 使用测试类 事务不自动提交的问题!!!
使用JUnit 测试hibernate 事务管理的时候应注意 ,测试类完成是默认回滚的. 所以只能查询数据库却不能增删改数据库. 应该在测试类上面加上注解 @Rollback(false) 表似默认 ...
- css让字体细长
transform: scale(1,3); -ms-transform: scale(1,3); -webkit-transform: scale(1,3); -moz-transform: sca ...
- windows 开启/关闭本地连接的批处理程序
::命令前加@符号,表示不显示@后面的命令. @echo off title Open / Close Network ::本地网络适配器名称 set name=以太网 ::查看网络状态,后反向设定 ...
- 工作中经常用到 github 上优秀、实用、轻量级、无依赖的插件和库
原文收录在 GitHub博客 ( https://github.com/jawil/blog ) ,喜欢的可以关注最新动态,大家一起多交流学习,共同进步,以学习者的身份写博客,记录点滴. 由于gith ...
- ERROR 1045 (28000): Access denied for user 'xxx'@'localhost' (using password: YES)
# Bug描述 今天周末,在家里学点新技术,虽然公司分配的任务没有完成(滑稽滑稽) 我先创建了一个mysql数据库,用root用户创建一个新用户,毕竟项目中使用root是非常危险的,尤其是我这样的实 ...
- linux/linux学习笔记-Shell基础(mooc)
一.shell概述 shell根据ascII表,将命令翻译为0101...传给内核执行. 内核->shell翻译为命令->用户(操作的界面就是shell,shell=翻译官) linux标 ...
- C函数调用过程原理及函数栈帧分析(转)
在x86的计算机系统中,内存空间中的栈主要用于保存函数的参数,返回值,返回地址,本地变量等.一切的函数调用都要将不同的数据.地址压入或者弹出栈.因此,为了更好地理解函数的调用,我们需要先来看看栈是怎么 ...
- java基础笔记(10)
Html:载体 CSS:样式 JavaScript:特效 html: 1. <html></html>称为根标签,所有的网页标签都在<html>< ...
- centos7 安装redis 出现cc: command not found错误解决
安装过程 1. 下载并解压 cd /root/software wget http://download.redis.io/releases/redis-3.2.4.tar.gz tar -zxvf ...
- C++关于erase的复杂度(转载)
被这个问题困扰了很多次,有必要整理一下. 当然最好的参考资料就是http://www.cplusplus.com/reference/set/set/erase/ 里的Complexcity部分了,但 ...