[洛谷P4910]帕秋莉的手环
2024-08-27 00:31:34
题目大意:有一个$n(n\leqslant10^{18})$个点的环,每个点可以是$0$或$1$,要求相邻点中至少一个$1$,问方案数,多组询问。
题解:先考虑是一条链的情况,令$f_{i,j}$表示到了第$i$个点,这个点是$j$的方案数。
$$
f_{i+1,0}=f_{i,1}\\
f_{i+1,1}=f_{i,0}+f_{i,1}
$$
再考虑一个环的情况,当第一点为$0$时,最后一个点只能选$1$,否则都可以。然后发现是$F_{n-1}+F_{n+1}$($F_n$表示斐波那契数列第$n$项)
卡点:传值时把$long\;long$传成$int$
C++ Code:
#include <cstdio>
const int mod = 1e9 + 7;
inline int getreduce(int x) { return x + (x >> 31 & mod); } struct Matrix {
int s[2][2];
inline Matrix operator * (const Matrix &rhs) {
Matrix res;
for (int i = 0; i < 2; ++i)
for (int j = 0; j < 2; ++j) {
long long t = 0;
for (int k = 0; k < 2; ++k) t += static_cast<long long> (s[i][k]) * rhs.s[k][j];
res.s[i][j] = t % mod;
}
return res;
}
} base, res;
inline int calc(long long n) {
if (!n) return 0;
if (n == 1) return 1;
res.s[0][0] = res.s[0][1] = 1;
base.s[0][0] = base.s[0][1] = base.s[1][0] = 1, base.s[1][1] = 0;
for (n -= 2; n; n >>= 1, base = base * base) if (n & 1) res = res * base;
return **res.s;
} int Tim;
long long n;
int main() {
scanf("%d", &Tim);
while (Tim --> 0) {
scanf("%lld", &n);
printf("%d\n", getreduce(calc(n - 1) + calc(n + 1) - mod));
}
return 0;
}
最新文章
- Subsonic简单的语法整理
- N-Queens leetcode
- jquery .filter()过滤器
- ERROR 2003: Can&#39;t connect to MySQL server on &#39;localhost&#39; (10061)
- [LeetCode#82]Remove Duplicates from Sorted Array II
- Ext.Msg.alert添加确定按钮
- 【毕业原版】-《贝德福特大学毕业证书》Bedfordhire一模一样原件
- 20165323 结对编程之四则运算week2-整体总结
- angular笔记_4(函数)
- 观察者模式之一:java实现观察者模式
- Ring0 - 链表
- Nginx错误提示:504 Gateway Time-out解决方法
- 和我一起学《HTTP权威指南》——连接管理
- 2015.7.8js-05(简单日历)
- 二、安装并配置Kubernetes Master节点
- Windows 环境下使用强大的wget工具
- Centos6.5安装JDK环境
- List泛型集合转DataTable
- spring4-3-AOP-AspectJ注解-01-简单使用
- MYSQL连接相关参数和状态值详解