您的位置:首页
HDU 2254 奥运(矩阵高速幂+二分等比序列求和)
2017-08-07 15:16
375 查看
HDU 2254 奥运(矩阵高速幂+二分等比序列求和)
ACM
题目地址:HDU 2254 奥运
题意:
中问题不解释。
分析:
依据floyd的算法,矩阵的k次方表示这个矩阵走了k步。
所以k天后就算矩阵的k次方。
这样就变成:初始矩阵的^[t1,t2]这个区间内的v[v1][v2]的和。
所以就是二分等比序列求和上场的时候了。
跟HDU 1588 Gauss Fibonacci的算法一样。
代码:
/* * Author: illuz <iilluzen[at]gmail.com> * Blog: http://blog.csdn.net/hcbbt * File: 2254.cpp * Create Date: 2014-08-04 10:52:29 * Descripton: matrix, floyd */ #include <cstdio> #include <cstring> #include <iostream> #include <map> #include <algorithm> using namespace std; #define repf(i,a,b) for(int i=(a);i<=(b);i++) typedef long long ll; const int N = 20; const int SIZE = 32; // max size of the matrix const int MOD = 2008; int n, k, p1, p2; ll v1, v2, t1, t2; map<int, int> mp; struct Mat{ int n; ll v[SIZE][SIZE]; // value of matrix Mat(int _n = SIZE) { n = _n; } void init(ll _v = 0) { memset(v, 0, sizeof(v)); if (_v) repf (i, 0, n - 1) v[i][i] = _v; } void output() { repf (i, 0, n - 1) { repf (j, 0, n - 1) printf("%lld ", v[i][j]); puts(""); } puts(""); } } a, b; Mat operator * (Mat a, Mat b) { Mat c(a.n); repf (i, 0, a.n - 1) { repf (j, 0, a.n - 1) { c.v[i][j] = 0; repf (k, 0, a.n - 1) { c.v[i][j] += (a.v[i][k] * b.v[k][j]) % MOD; c.v[i][j] %= MOD; } } } return c; } Mat operator ^ (Mat a, ll k) { Mat c(a.n); c.init(1); while (k) { if (k&1) c = a * c; a = a * a; k >>= 1; } return c; } Mat operator + (Mat a, Mat b) { Mat c(a.n); repf (i, 0, a.n - 1) repf (j, 0, a.n - 1) c.v[i][j] = (b.v[i][j] + a.v[i][j]) % MOD; return c; } Mat operator + (Mat a, ll b) { Mat c = a; repf (i, 0, a.n - 1) c.v[i][i] = (a.v[i][i] + b) % MOD; return c; } Mat calc(Mat a, int n) { if (n == 1) return a; if (n&1) return (a^n) + calc(a, n - 1); else return calc(a, n/2) * ((a^(n/2)) + 1); } int main() { while (~scanf("%d", &n)) { a.init(); mp.clear(); int cnt = 0; while (n--) { scanf("%d%d", &p1, &p2); if (mp.find(p1) == mp.end()) p1 = mp[p1] = cnt++; else p1 = mp[p1]; if (mp.find(p2) == mp.end()) p2 = mp[p2] = cnt++; else p2 = mp[p2]; a.v[p1][p2]++; } a.n = cnt; scanf("%d", &k); while (k--) { scanf("%lld%lld%lld%lld", &v1, &v2, &t1, &t2); if (mp.find(v1) == mp.end() || mp.find(v2) == mp.end()) { puts("0"); continue; } v1 = mp[v1]; v2 = mp[v2]; if (t1 > t2) swap(t1, t2); if (t1 == 0) { if (t2 == 0) puts("0"); else printf("%lld\n", calc(a, t2).v[v1][v2]); } else if (t1 == 1) printf("%lld\n", calc(a, t2).v[v1][v2]); else { printf("%lld\n", ((calc(a, t2).v[v1][v2] - calc(a, t1 - 1).v[v1][v2]) + MOD) % MOD); } } } return 0; }
相关文章推荐
- HDU 2254 奥运(矩阵快速幂+二分等比序列求和)
- HDU 1588 Gauss Fibonacci(矩阵高速幂+二分等比序列求和)
- hdu 2254 奥运(矩阵降幂+二分求和)
- HDU 1588 Gauss Fibonacci(矩阵快速幂+二分等比序列求和)
- hdu 1588 Gauss Fibonacci(等比矩阵二分求和)
- HDU 1588 二分矩阵连乘求和
- 考研路茫茫——单词情结 HDU - 2243 AC自动机/特征字符串构造计数/等比矩阵求和
- hdu 2254 奥运(矩阵 感觉挺难的)
- HDU 2254 奥运 矩阵应用
- POJ 3233 Matrix Power Series (矩阵乘法+快速幂+等比二分求和) -
- HDU 1588(数论,构造二分矩阵+求幂运算+二分求和)
- HDU - 1588 Gauss Fibonacci (矩阵高速幂+二分求等比数列和)
- hdu 1588 Gauss Fibonacci 矩阵的高次高速求幂,矩阵的高速求和,斐波那契公式
- HDU 2254 奥运(矩阵)
- HDU1588-Gauss Fibonacci(矩阵高速幂+等比数列二分求和)
- hdu 1588 Gauss Fibonacci(函数嵌套、转换、等比矩阵求和)
- POJ - 3233 Matrix Power Series (矩阵等比二分求和)
- HDU 2254 奥运(矩阵)
- hdu 2254 奥运(矩阵快速幂)
- HDU 2254 奥运(数论+矩阵)