题意

多组数据,给出一个环,要求不能有连续的\(1\),求出满足条件的方案数

\(1\le T \le 10, 1\le n \le 10^{18}\)

思路

20pts

暴力枚举(不会写

60pts

假设金珠子为\(0\),木珠子为\(1\),则不能有连续的木珠子

线性递推\(DP\),设\(f[i][0/1]\)表示当前填到第\(i\)位,第\(i\)位为金珠子/木珠子的方案数,那么有:

\[f[i][0] = f[i - 1][0] + f[i - 1][1]
\]

\[f[i][1] = f[i-1][0]
\]

但是要分成两种情况讨论

  • 第一个位置是\(0\),则\(f[1][0]=1,f[1][1]=0\),那么最后一个位置可以是\(0\)也可以是\(1\)

    所以此时对答案的贡献为\(f[n][0]+f[n][1]\)

  • 第一个位置是\(1\),则\(f[1][1]=1,f[1][0]=0\),那么最后一个位置只能是\(0\)

    所以此时对答案的贡献为\(f[n][0]\)

时间复杂度\(O(Tn)\),期望得分\(60\)分

不知道为什么,也许是我写假了,只有48分

100pts

考虑用矩阵优化,目前的状态为\([f_{i,0},f_{i,1}]\),目标状态为\([f_{i+1,0},f_{i+1,1}]\),比较容易推出转移矩阵为

\[[f_{i,0},f_{i,1}] * \left[ \begin{matrix} 1 & 1 \\ 1 & 0 \end{matrix} \right] = [f_{i+1,0},f_{i+1,1}]
\]

按照\(60\)分做法写矩阵快速幂就好了

代码

60pts

  1. /*
  2. Author:loceaner
  3. 假设不能有连续的1
  4. 用f[i][0/1]表示选到了i处,第i处为白/黑的方案数
  5. f[i][1] = f[i - 1][0]
  6. f[i][0] = f[i - 1][1] + f[i - 1][0]
  7. */
  8. #include <cmath>
  9. #include <cstdio>
  10. #include <cstring>
  11. #include <iostream>
  12. #include <algorithm>
  13. using namespace std;
  14. const int A = 1e6 + 10000;
  15. const int B = 1e6 + 11;
  16. const int mod = 1000000007;
  17. const int inf = 0x3f3f3f3f;
  18. inline int read() {
  19. char c = getchar(); int x = 0, f = 1;
  20. for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
  21. for( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
  22. return x * f;
  23. }
  24. int n, f[A][2];
  25. int main() {
  26. int T = read();
  27. while(T--) {
  28. n = read();
  29. long long ans = 0;
  30. f[1][0] = 1, f[1][1] = 0;
  31. for (int i = 2; i <= n; i++) {
  32. f[i][1] = f[i - 1][0] % mod;
  33. f[i][0] = (f[i - 1][1] + f[i - 1][0]) % mod;
  34. }
  35. ans = (f[n][0] + f[n][1]) % mod;
  36. f[1][0] = 0, f[1][1] = 1;
  37. for (int i = 2; i <= n; i++) {
  38. f[i][1] = f[i - 1][0] % mod;
  39. f[i][0] = (f[i - 1][1] + f[i - 1][0]) % mod;
  40. }
  41. (ans += f[n][0]) %= mod;
  42. cout << ans << '\n';
  43. }
  44. return 0;
  45. }

100pts

  1. /*
  2. Author:loceaner
  3. */
  4. #include <cmath>
  5. #include <cstdio>
  6. #include <cstring>
  7. #include <iostream>
  8. #include <algorithm>
  9. #define int long long
  10. using namespace std;
  11. const int A = 1e6 + 10000;
  12. const int B = 1e6 + 11;
  13. const int mod = 1000000007;
  14. const int inf = 0x3f3f3f3f;
  15. inline int read() {
  16. char c = getchar(); int x = 0, f = 1;
  17. for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
  18. for( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
  19. return x * f;
  20. }
  21. int n;
  22. struct mat { int a[2][2]; } a, b, c;
  23. mat operator * (const mat &a, const mat &b) {
  24. mat c;
  25. memset(c.a, 0, sizeof(c.a));
  26. for (int k = 0; k <= 1; k++)
  27. for (int i = 0; i <= 1; i++)
  28. for (int j = 0; j <= 1; j++)
  29. c.a[i][j] = (c.a[i][j] + a.a[i][k] % mod * b.a[k][j] % mod) % mod;
  30. return c;
  31. }
  32. mat ksm(mat a, int b) {
  33. mat ans;
  34. memset(ans.a, 0, sizeof(ans.a));
  35. for (int i = 0; i <= 1; i++) ans.a[i][i] = 1;
  36. while (b) {
  37. if (b & 1) ans = ans * a;
  38. a = a * a, b >>= 1;
  39. }
  40. return ans;
  41. }
  42. signed main() {
  43. int T = read();
  44. while(T--) {
  45. n = read();
  46. int ans = 0;
  47. memset(a.a, 0, sizeof(a.a));
  48. a.a[0][0] = a.a[0][1] = a.a[1][0] = 1;
  49. a = ksm(a, n - 1);
  50. memset(b.a, 0, sizeof(b.a));
  51. b.a[0][0] = 1, b = b * a;
  52. ans = (ans + b.a[0][0] % mod + b.a[0][1]) % mod;
  53. memset(c.a, 0, sizeof(c.a));
  54. c.a[0][1] = 1, c = c * a;
  55. ans = (ans + c.a[0][0]) % mod;
  56. cout << ans << '\n';
  57. }
  58. }

洛谷 P4910 帕秋莉的手环的更多相关文章

  1. 洛谷 P4910 帕秋莉的手环 矩阵乘法+快速幂详解

    矩阵快速幂解法: 这是一个类似斐波那契数列的矩乘快速幂,所以推荐大家先做一下下列题目:(会了,差不多就是多倍经验题了) 注:如果你不会矩阵乘法,可以了解一下P3390的题解 P1939 [模板]矩阵加 ...

  2. [洛谷P4910]帕秋莉的手环

    题目大意:有一个$n(n\leqslant10^{18})$个点的环,每个点可以是$0$或$1$,要求相邻点中至少一个$1$,问方案数,多组询问. 题解:先考虑是一条链的情况,令$f_{i,j}$表示 ...

  3. P4910 帕秋莉的手环

    题目背景 帕秋莉是蕾米莉亚很早结识的朋友,现在住在红魔馆地下的大图书馆里.不仅擅长许多魔法,还每天都会开发出新的魔法.只是身体比较弱,因为哮喘,会在咏唱符卡时遇到麻烦. 她所用的属性魔法,主要是生命和 ...

  4. [Luogu] P4910 帕秋莉的手环

    题目背景 帕秋莉是蕾米莉亚很早结识的朋友,现在住在红魔馆地下的大图书馆里.不仅擅长许多魔法,还每天都会开发出新的魔法.只是身体比较弱,因为哮喘,会在咏唱符卡时遇到麻烦. 她所用的属性魔法,主要是生命和 ...

  5. 【题解】Luogu P4910 帕秋莉的手环

    原题传送门 "连续的两个中至少有1个金的"珂以理解为"不能有两个木相连" 我们考虑一个一个将元素加入手环 设f\([i][0/1]\)表示长度为\(i\)手环末 ...

  6. 【Cogs2187】帕秋莉的超级多项式(多项式运算)

    [Cogs2187]帕秋莉的超级多项式(多项式运算) 题面 Cogs 题解 多项式运算模板题 只提供代码了.. #include<iostream> #include<cstdio& ...

  7. cogs 998. [東方S2] 帕秋莉·诺蕾姬

    二次联通门 : cogs 998. [東方S2] 帕秋莉·诺蕾姬 交上去后发现自己没上榜 就想着加点黑科技 把循环展开一下 结果WA了.. 万恶的姆Q /* cogs 998. [東方S2] 帕秋莉· ...

  8. P4915 帕秋莉的魔导书(动态开点线段树)

    题目背景 帕秋莉有一个巨大的图书馆,里面有数以万计的书,其中大部分为魔导书. 题目描述 魔导书是一种需要钥匙才能看得懂的书,然而只有和书写者同等或更高熟练度的人才能看得见钥匙.因此,每本魔导书都有它自 ...

  9. COGS2187 [HZOI 2015] 帕秋莉的超级多项式

    什么都别说了,咱心态已经炸了... question 题目戳这里的说... 其实就是叫你求下面这个式子的导函数: noteskey 其实是道板子题呢~ 刚好给我们弄个多项式合集的说... 各种板子粘贴 ...

随机推荐

  1. 温故知新-多线程-深入刨析CAS

    文章目录 摘要 CAS是什么? CAS是如何实现的? CAS存在的问题? 你的鼓励也是我创作的动力 Posted by 微博@Yangsc_o 原创文章,版权声明:自由转载-非商用-非衍生-保持署名 ...

  2. ELK 收集交换机日志(以华为交换机为例)

    大概思路 交换机日志----> 服务器---->服务器rsyslog设置指定存储路径文件--->随后就跟elk 监控本机日志一样了 huawei switch: #指定发送消息基本, ...

  3. 最新 iOS 框架整体梳理(二)

    在前面一篇中整理出来了一些了,下面的内容是接着上面一篇的接着整理.上篇具体的内容可以点击这里查看:   最新 iOS 框架整体梳理(一) Part - 2          34.CoreTeleph ...

  4. 3.vue计算属性

    1.计算属性  再vue中如果出现表达式过长或者逻辑比较复杂,这时会导致代码不清晰,臃肿,难以维护所以我们会使用计算属性进行书写  再计算属性中可以放负责的逻辑,可以是函数,表达式等,但最终会返回一个 ...

  5. 01 . Docker原理部署及常用操作命令

    Docker的来源及构造: 容器是一种基础工具:泛指任何用于容纳其他物品的工具,可以部分或完全封闭,被用于容纳,储存,运输物品: 物品可以被放置在容器中,而容器可以保护内容物: 人类使用容器的历史有十 ...

  6. C++中类成员的访问控制

    结论 首先给出结论,请看下图,看图说话最容易理解了. 类眼中的自己 类中定义的所有成员,不论是以public, protected还是private修饰,对类自身而言,它们都是可见的. 对象眼中的类 ...

  7. Deno 初探

    前言 Deno 已经被前端圈子提及有很长一段时间了,上个月 Deno 发布了 1.0 版本,又掀起了一小股 Deno 热.Deno 到底是什么?它可以用来做什么呢?它好用吗?带着一直以来的好奇心,趁着 ...

  8. Android SDK 安装与配置

    1.下载sdk包 链接:https://pan.baidu.com/s/1Og8F02YBJn59LPWsJwkjUA 提取码:byu1 复制这段内容后打开百度网盘手机App,操作更方便哦 2.解压 ...

  9. 《Java并发编程的艺术》第4章 Java并发编程基础 ——学习笔记

    参考https://www.cnblogs.com/lilinzhiyu/p/8086235.html 4.1 线程简介 进程:操作系统在运行一个程序时,会为其创建一个进程. 线程:是进程的一个执行单 ...

  10. cc31a_demo--CppPrimer_静态成员与继承-在派生类中访问基类中的static成员的方法

    //*基类中的static成员,在整个继承层次中只有一个实例 //*在派生类中访问基类中的static成员的方法 //1.基类名::成员名 //2.子类名::成员名 //3.对象.成员名 //4.指针 ...