【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年提出的一种抽象计算模型,其更抽象的意义为一种数学逻辑机,可以看作等价于任何有限逻辑数学过程的终极强大逻 ...
随机推荐
- Delphi XE2 之 FireMonkey 入门(34) - 控件基础: TFmxObject: 克隆对象
Delphi XE2 之 FireMonkey 入门(34) - 控件基础: TFmxObject: 克隆对象 有两个和克隆相关的方法: Clone().CloneChildFromStream(). ...
- rename()函数(包含更改索引列列名的方法)
1 rename()可以更换列名和行名,必须写上columns或index,否则无效 import pandas as pd df = pd.DataFrame({'a':[1,2], 'b':[3, ...
- C# Hook 方法
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.R ...
- ES 集群管理(集群规划、集群搭建、集群管理)
一.集群规划 搭建一个集群我们需要考虑如下几个问题: 1. 我们需要多大规模的集群? 2. 集群中的节点角色如何分配? 3. 如何避免脑裂问题? 4. 索引应该设置多少个分片? 5. 分片应该设置几个 ...
- 每次进步一点点——linux expect 使用
1. 介绍 expect是建立在tcl(参见:Tcl/Tk快速入门 )基础上的一个工具,它可以让一些需要交互的任务自动化地完成.相当于模拟了用户和命令行的交互操作. 一个具体的场景:远程登陆服务器,并 ...
- linux下搭建mysql数据库
linux下搭建mysql数据库 1.下载mysql: http://dev.mysql.com/downloads/mysql/5.6.html#downloads wget http://dev. ...
- 【Qt开发】如何将内存图像数据封装成QImage V1
如何将内存图像数据封装成QImage 当采用Qt开发相机数据采集软件时,势必会遇到采集内存图像并进行处理(如缩放.旋转)操作.如果能够将内存图像数据封装成QImage,则可以利用QImage强大的图像 ...
- es7.4.0集群部署
其实主要是配置的变化,需要指定下master节点 cluster.name: prod-es node.name: node1 node.master: true node.data: true pa ...
- MySQL-快速入门(9)视图
1.什么是视图 视图是一个虚表.视图可以进行查询.增加.修改.删除.进行修改.增加.删除,将影响基本表中的数据. 2.视图相对基本表的优势 1>简单化:看到的就是想要的字段列,可以简化后续查询. ...
- Java数据结构之栈(Stack)
1.栈(Stack)的介绍 栈是一个先入后出(FILO:First In Last Out)的有序列表. 栈(Stack)是限制线性表中元素的插入和删除只能在同一端进行的一种特殊线性表. 允许插入和删 ...