矩阵乘法 + 快速幂优化递推:

看到这个题目我们不难想到递推,题干中说3个连续的A出现在序列中是不合法的,所以可以分为三种情况:

(1):序列前只有一个A,如:BA,BBA,BABA。

(2):序列前有两个A,如:BAA,BBAA,BABAA。

(3):序列前没有A而是B,如:BB,AB,AABAAB。

我们将这三种情况分别用 a1 , a2 , b 表示。

  1. // a1:1 1 2 4 7 13 24 44 81 149 274
  2. // a2:0 1 1 2 4 7 13 24 44 81 149 274
  3. // b :1 2 4 7 13 24 44 81 149 274

我们不难发现在下一轮加A或加B时:a1可以转化为a2,a1和a2都可以转化为b,而b又可以转化为a1或再加一个b不变;

故规律为:

  1. // f=a2;
  2. // a2=a1;
  3. // a1=b;
  4. // b=(a1+a2+f)%19260817;

注意变量会相互覆盖掉,f是借来存值的;

这是代码:

  1. #include<iostream>
  2. using namespace std;
  3. int m,n,i,a1,a2,b1,f;
  4. int main(){
  5. cin>>m;
  6. while(m--){
  7. cin>>n;
  8. a1=1;b1=1;a2=0;
  9. for(i=2;i<=n;i++){
  10. f=a2;a2=a1;a1=b1;
  11. b1=(a1+a2+f)%19260817;
  12. }
  13. cout<<(a1+a2+b1)%19260817<<endl;
  14. }
  15. return 0;
  16. }

但是!

这题如果这么简单也就不会是蓝题了(其实上面那个代码也能拿80分的)。

我们知道一般递推复杂度为o(n),而这题数据范围中n<=(10^9),还可以问十次,绝对会超时的!

这里提供两种优化方案:

(1):

注:这是个打表不正经超有用骗满分暴力的方法:

测评姬只给你一秒时限,但你可以在自己电脑上算很久都没问题。

所以你可以在电脑上先算出从一开始每隔(10^7)位的三个递推数;当程序读入n时找到离n最近的递推数开始递推。

简单来说就是你可以在数组中先存下(108)的三个递推数a1,a2和b,这样就能直接从(108)开始递推到n;估计能比正解还快不少!

(2):

注:其实这里才进入主题,上面可以当做都是准备工作。

注:本蒟蒻也是今天才了解矩乘优化的QAQ,若有写的不好的地方各位大佬见谅。

我们先来了解一下矩阵:

矩阵就是一个二维方阵,矩阵A的第i行第j列可用A(i,j)来表示.

一个n行m列的矩阵A就是这样:

A(1,1) A(1,2) A(1,3) ... A(1,m)

A(2,1) A(2,2) A(2,3) ... A(2,m)

A(3,1) A(3,2) A(3,3) ... A(3,m)

...

A(n,1) A(n,2) A(n,3) ... A(n,m)

而矩阵乘法就是矩阵的一种运算

那么矩阵乘法的对象就是两个矩阵A和B,

注意:矩阵A的列数要与矩阵B的行数相等!

那么运算的答案矩阵C的第i行第j列即为:

C(i,j)=A(i,1)B(1,j)+A(i,2)B(2,j)+...+A(i,p)*B(p,j);

如下:

  1. int jucheng(int n,int p,int m){
  2. memset(c,0,sizeof(c));
  3. for (int i=1;i<=n;i++)
  4. for (int j=1;j<=m;j++)//p为矩阵A的列数与矩阵B的行数
  5. for (int k=1;k<=p;k++) //枚举的所有递推数
  6. c[i][j]+=a[i][k]*b[k][j] //公式
  7. }

矩阵乘法不满足交换律,但满足结合律.

AB!=BA

(AB)C=A(BC)

矩阵乘法也可以同余.

而当我们将矩阵乘法用到递推中时:

举一例:斐波那契数列:f[i]=f[i-1]+f[i-2].

把它用矩阵乘法表示:

  1. // A(1,1) A(1,2)
  2. // [0 1]* =[1 1]
  3. // A矩阵 A(2,1) A(2,2) C矩阵
  4. // B矩阵

不难根据公示得出B矩阵为

  1. 0,1
  2. 1,1

故递推矩阵为:

  1. // 0 1
  2. //[ f[i] f[i+1] ]* =[ f[i+1] f[i]+f[i+1] ]=[ f[i+1] f[i+2] ]
  3. // 1 1

而本题中的递推矩阵为:

  1. 1,1,1
  2. 1,0,0
  3. 0,1,0

本题大意就是要将此矩阵反复乘n次。这就可以用快速幂了!

下面现上代码:

  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. struct ju{
  4. long long s[3][3];
  5. };
  6. ju cheng(ju a,ju b){//矩乘函数:
  7. ju c;
  8. for(int i=0;i<3;i++)for(int j=0;j<3;j++)c.s[i][j]=0;
  9. for(int i=0;i<3;i++)
  10. for(int j=0;j<3;j++)
  11. for(int k=0;k<3;k++)
  12. c.s[i][j]+=a.s[i][k]*b.s[k][j],c.s[i][j]%=19260817;
  13. return c;
  14. }
  15. ju fast(int n){//快速幂:
  16. ju c,d;
  17. c.s[0][0]=c.s[0][1]=c.s[0][2]=c.s[1][0]=c.s[2][1]=1;
  18. c.s[1][1]=c.s[1][2]=c.s[2][0]=c.s[2][2]=0;
  19. if(n==1)return c;//
  20. d=fast(n/2);//这个很关键
  21. if(n%2==0)return cheng(d,d);
  22. return cheng(cheng(d,d),c);//多了一个1要再多乘1次
  23. }
  24. void print(ju n){// 输出:
  25. cout<<(n.s[0][0]+n.s[0][1])%19260817<<endl;
  26. }
  27. int main(){
  28. int m,n;
  29. cin>>m;
  30. while(m--){//一个一个算:
  31. cin>>n;
  32. print(fast(n));
  33. }
  34. return 0;//圆满
  35. }

码字挺累的(手残党,码了两小时了QAQ),大家点个赞再走吧。

洛谷 P4838 P哥破解密码 题解的更多相关文章

  1. [洛谷P4838]P哥破解密码

    题目大意:求长度为$n$的$01$串中,没有连续至少$3$个$1$的串的个数 题解:令$a_1$为结尾一个$1$的串个数,$a_2$为结尾两个$1$的串的个数,$b$为结尾是$0$的串的个数.$a_1 ...

  2. 【题解】Luogu P4838 P哥破解密码

    原题传送门 考虑一个一个将字母加入字符串后面 设\(f[i][0/1/2]\)表示长度为\(i\)字符串末尾有\(0/1/2\)个A的种类数 易知: \(f[1][0]=1,f[1][1]=1,f[1 ...

  3. P4838 P哥破解密码

    题目背景 P哥是一个经常丢密码条的男孩子. 在ION 8102赛场上,P哥又弄丢了密码条,笔试满分的他当然知道这可是要扣5分作为惩罚的,于是他开始破解ION Xunil系统的密码. 题目描述 定义一个 ...

  4. [Luogu] P4838 P哥破解密码

    题目背景 P哥是一个经常丢密码条的男孩子. 在ION 8102赛场上,P哥又弄丢了密码条,笔试满分的他当然知道这可是要扣5分作为惩罚的,于是他开始破解ION Xunil系统的密码. 题目描述 定义一个 ...

  5. 洛谷P1854 花店橱窗布置 分析+题解代码

    洛谷P1854 花店橱窗布置 分析+题解代码 蒟蒻的第一道提高+/省选-,纪念一下. 题目描述: 某花店现有F束花,每一束花的品种都不一样,同时至少有同样数量的花瓶,被按顺序摆成一行,花瓶的位置是固定 ...

  6. HAOI2006 (洛谷P2341)受欢迎的牛 题解

    HAOI2006 (洛谷P2341)受欢迎的牛 题解 题目描述 友情链接原题 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之 ...

  7. 洛谷P3412 仓鼠找$Sugar\ II$题解(期望+统计论?)

    洛谷P3412 仓鼠找\(Sugar\ II\)题解(期望+统计论?) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/1327573 原题链接:洛谷P3412 ...

  8. 洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速$dp\&Floyd$)

    洛谷P3502 [POI2010]CHO-Hamsters感想及题解(图论+字符串+矩阵加速\(dp\&Floyd\)) 标签:题解 阅读体验:https://zybuluo.com/Junl ...

  9. BZOJ4946 & 洛谷3826 & UOJ318:[NOI2017]蔬菜——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4946 https://www.luogu.org/problemnew/show/P3826 ht ...

随机推荐

  1. 科普贴 | 数字钱包MetaMask安装使用详解,活用MetaMask轻松驾驭以太坊

    MetaMask 是一款浏览器插件钱包,不需下载安装客户端,只需添加至浏览器扩展程序即可使用,非常方便.它是很多支持 ETH 参投的 ICO 项目推荐使用的钱包之一. 2018年初最火的一个币,应该就 ...

  2. 基于spring框架的apache shiro简单集成

    关于项目的安全保护,我一直想找一个简单配置就能达到目的的方法,自从接触了shiro,这个目标总算达成了,以下结合我使用shiro的经验,谈谈比较轻便地集成该功能. 首先我们先了解一下shiro是什么. ...

  3. 关于sql server2008数据库的连接的几个问题及解决办法

    写在开头 不得不说给一台新的服务器配置和部署的确是个不小的工程,在这里先感谢我们的DEV焉域政同学在这方面做出的一些贡献:把安装过程极为困难的sql server2008成功安装到服务器上,并且为我们 ...

  4. PowerDesigner16工具学习笔记-建立CDM

    1.基本术语 1.1.实体和属性 实体(entity):指现实世界中客观存在,并可相互区别的事物或者事件. 属性(attribute):一组用来描述实体特征的属性. 实体集(entity set):具 ...

  5. ios UnitTest 学习笔记

    一.运行第一个单元测试: 1.在Xcode 5中新建一个工程默认自带一个单元测试的文件夹,IDE自动生成了一个实现XCTestCase的.m文件,里面有一个失败测试(早期版本中实现的是SenTestC ...

  6. 深入理解Java反射+动态代理

    答:   反射机制的定义: 是在运行状态中,对于任意的一个类,都能够知道这个类的所有属性和方法,对任意一个对象都能够通过反射机制调用一个类的任意方法,这种动态获取类信息及动态调用类对象方法的功能称为j ...

  7. nodejs nodemailer 使用

    index.js const nodemailer=require("nodemailer") let sendEmail=function () { var transporte ...

  8. delphi Form属性设置 设置可实现窗体无最大化,并且不能拖大拖小

    以下设置可实现窗体无最大化,并且不能拖大拖小BorderIcon 设为---biMax[False] biHelp [False]BorderStyle 设为---bsSingle 参考------- ...

  9. maven测试时中文乱码问题解决方法

    pom.xml增加-Dfile.encoding=UTF-8配置,如下: <plugin> <!--升级到新版本解决控制台乱码问题--> <groupId>org. ...

  10. MVC 锚点

    MVC 锚点 linkText:生成的链接所显示的文字 actionName:对应控制器的方法 routeValues:向对应的action传递的参数 controlName:指定控制器的名称 htm ...