BZOJ 2326 HNOI 2011 数学作业 矩阵乘法求数列第n项
2015-12-02 19:28
537 查看
对于fn=12345678910...n,有fn=fn-1*(10^(floor(lgn)+1))+n。
所以构造矩阵:
10^(floor(lgn)+1) 0 0
1 1 0
0 1 1
实际上,对于1位数就是10^1,2位数就是10^2。每次矩阵乘够10^i-10^(i-1)即可,其中i表示位数,最后一次乘的次数不一样.
发现换了一种写法程序就麻烦了好多。。。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; typedef unsigned long long ll; #define FOR(i,j,k) for(i=j;i<=k;i++) ll read() { ll s = 0; char ch = getchar(); while (ch < '0' || ch > '9') ch = getchar(); while ('0' <= ch && ch <= '9') s = s * 10 + ch - '0', ch = getchar(); return s; } ll n, p; struct Matrix { ll a[4][4]; Matrix(int flag) { int i, j; FOR(i,1,3) FOR(j,1,3) a[i][j] = flag & (i == j); } Matrix(bool, ll digit) { a[1][1] = digit; a[2][1] = a[2][2] = a[3][2] = a[3][3] = 1; a[1][3] = a[1][2] = a[2][3] = a[3][1] = 0; } ll* operator [] (int x) { return a[x]; } friend void operator *= (Matrix &x, Matrix y) { int i, j, k; Matrix z(0); FOR(i,1,3) FOR(j,1,3) FOR(k,1,3) z[i][j] = (z[i][j] + x[i][k] * y[k][j]) % p; x = z; } friend Matrix operator ^(Matrix x, ll y) { Matrix re(1); for (; y; x *= x, y >>= 1) if(y & 1) re *= x; return re; } } ans(1); int main() { ll i; n = read(); p = read(); for (i = 10; i <= n; i *= 10) ans *= Matrix(1, i % p) ^ (i - i / 10); ans *= Matrix(1, i % p) ^ (n - i / 10 + 1); printf("%llu", (ans[2][1] + ans[3][1]) % p); return 0; }
相关文章推荐
- POJ3268 求最长路径(一来一回)
- sleep()与wait()之间的不同
- Effective Objective-C 2.0: Item 41: Prefer Dispatch Queues to Locks for Synchronization
- static
- leetcode-ZigZag Convertion
- 同页面javascript中文参数传递
- Codeforces Round #334 (Div. 2) 题解
- containing working copy admin area is missing
- 算法学习---查找(二)-二分查找
- MySQL 常用的UPDATE操作
- hdoj Girls' research (字符串&manacher)
- [Android学习笔记九] Android 开发中图片灰阶(黑白)显示
- BZOJ 2165 大楼 类矩阵乘法/倍增Floyd 二进制判断状态
- RegExp 对象(正则表达式)
- Handler源码解析
- AliceBot在Idea中通过maven构建
- 2015-12-02活动目录中的组的类型和功能
- 通过ViewPager控件实现多张图片动态切换
- JAVA io流 文件流 字节流 字符流 过滤流 缓冲流
- Android中开辟线程(下载-网络连接)