题意

多组数据,给出一个环,要求不能有连续的\(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

/*
Author:loceaner
假设不能有连续的1
用f[i][0/1]表示选到了i处,第i处为白/黑的方案数
f[i][1] = f[i - 1][0]
f[i][0] = f[i - 1][1] + f[i - 1][0]
*/
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int A = 1e6 + 10000;
const int B = 1e6 + 11;
const int mod = 1000000007;
const int inf = 0x3f3f3f3f; inline int read() {
char c = getchar(); int x = 0, f = 1;
for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
return x * f;
} int n, f[A][2]; int main() {
int T = read();
while(T--) {
n = read();
long long ans = 0;
f[1][0] = 1, f[1][1] = 0;
for (int i = 2; i <= n; i++) {
f[i][1] = f[i - 1][0] % mod;
f[i][0] = (f[i - 1][1] + f[i - 1][0]) % mod;
}
ans = (f[n][0] + f[n][1]) % mod;
f[1][0] = 0, f[1][1] = 1;
for (int i = 2; i <= n; i++) {
f[i][1] = f[i - 1][0] % mod;
f[i][0] = (f[i - 1][1] + f[i - 1][0]) % mod;
}
(ans += f[n][0]) %= mod;
cout << ans << '\n';
}
return 0;
}

100pts

/*
Author:loceaner
*/
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define int long long
using namespace std; const int A = 1e6 + 10000;
const int B = 1e6 + 11;
const int mod = 1000000007;
const int inf = 0x3f3f3f3f; inline int read() {
char c = getchar(); int x = 0, f = 1;
for( ; !isdigit(c); c = getchar()) if(c == '-') f = -1;
for( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
return x * f;
} int n; struct mat { int a[2][2]; } a, b, c; mat operator * (const mat &a, const mat &b) {
mat c;
memset(c.a, 0, sizeof(c.a));
for (int k = 0; k <= 1; k++)
for (int i = 0; i <= 1; i++)
for (int j = 0; j <= 1; j++)
c.a[i][j] = (c.a[i][j] + a.a[i][k] % mod * b.a[k][j] % mod) % mod;
return c;
} mat ksm(mat a, int b) {
mat ans;
memset(ans.a, 0, sizeof(ans.a));
for (int i = 0; i <= 1; i++) ans.a[i][i] = 1;
while (b) {
if (b & 1) ans = ans * a;
a = a * a, b >>= 1;
}
return ans;
} signed main() {
int T = read();
while(T--) {
n = read();
int ans = 0;
memset(a.a, 0, sizeof(a.a));
a.a[0][0] = a.a[0][1] = a.a[1][0] = 1;
a = ksm(a, n - 1);
memset(b.a, 0, sizeof(b.a));
b.a[0][0] = 1, b = b * a;
ans = (ans + b.a[0][0] % mod + b.a[0][1]) % mod;
memset(c.a, 0, sizeof(c.a));
c.a[0][1] = 1, c = c * a;
ans = (ans + c.a[0][0]) % mod;
cout << ans << '\n';
}
}

洛谷 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. lambda表达式操作DataTable番外篇

    using System;using System.Collections.Generic;using System.Data;using System.Linq;using System.Text; ...

  2. (一)linux三剑客之grep

    给自己提出以下6个问题,看自己是否真正掌握了grep [1] grep 是什么? [2] grep 有什么作用 ? [4] grep 常用于何处 ? [5] grep 的基本用法 ? [6] grep ...

  3. kworkerds挖矿木马

    昨天一朋友的公司服务器中了挖矿病毒,一起帮忙查看并做下记录.   病毒信息 名称:kworkerds 目录:/tmp/ 关键点:文件 -i 属性   i :这个i可就很厉害了.它可以让一个文件“不能被 ...

  4. 「从零单排canal 02」canal集群版 + admin控制台 最新搭建姿势(基于1.1.4版本)

    canal [kə'næl],译意为水道/管道/沟渠,主要用途是基于 MySQL 数据库增量日志解析,提供增量数据 订阅 和 消费.应该是阿里云DTS(Data Transfer Service)的开 ...

  5. PAT1040 Longest Symmetric String (25分) 中心扩展法+动态规划

    题目 Given a string, you are supposed to output the length of the longest symmetric sub-string. For ex ...

  6. javascript 面向对象学习(一)——构造函数

    最近在学习设计模式,找了很多资料也没有看懂,看到怀疑智商,怀疑人生,思来想去还是把锅甩到基础不够扎实上.虽然原型继承.闭包.构造函数也都有学习过,但理解得不够透彻,影响到后续提高.这次重新开始学习,一 ...

  7. Jmeter(九) - 从入门到精通 - JMeter逻辑控制器 - 上篇(详解教程)

    1.简介 Jmeter官网对逻辑控制器的解释是:“Logic Controllers determine the order in which Samplers are processed.”. 意思 ...

  8. PHP源码进行加密(仅linux)

    加密软件(php_screw) 1.下载网站:http://sourceforge.net/projects/php-screw/ 2.描述: php文件通常以文本格式存贮在服务器端, 很容易被别人读 ...

  9. Python实现梯度法(最速上升(下降)法)寻找函数极大(极小)值

    首先简介梯度法的原理.首先一个实值函数$R^{n} \rightarrow R$的梯度方向是函数值上升最快的方向.梯度的反方向显然是函数值下降的最快方向,这就是机器学习里梯度下降法的基本原理.但是运筹 ...

  10. AWS 错误标记3

    1. What is the average queue length recommended by AWS to achieve a lower latency for the 200 PIOPS ...