HDU 5068 Harry And Math Teacher 线段树+矩阵乘法
2014-10-27 19:32
344 查看
题意:
一栋楼有n层,每一层有2个门,每层的两个门和下一层之间的两个门之间各有一条路(共4条)。
有两种操作:
0 x y : 输出第x层到第y层的路径数量。
1 x y z : 改变第x层 的 y门 到第x+1层的 z门的通断情况。
思路:
门之间的路径数可以用矩阵来表示,经过的中间层可以用矩阵乘积表示。 所以用线段树维护矩阵乘积即可。
代码:
View Code
一栋楼有n层,每一层有2个门,每层的两个门和下一层之间的两个门之间各有一条路(共4条)。
有两种操作:
0 x y : 输出第x层到第y层的路径数量。
1 x y z : 改变第x层 的 y门 到第x+1层的 z门的通断情况。
思路:
门之间的路径数可以用矩阵来表示,经过的中间层可以用矩阵乘积表示。 所以用线段树维护矩阵乘积即可。
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <cmath> #include <algorithm> #include <string> #include <queue> #include <stack> #include <vector> #include <map> #include <set> #include <functional> #include <cctype> #include <time.h> using namespace std; typedef __int64 ll; const int INF = 1<<30; const int MAXN = 5e4+55; const ll MOD = 1e9+7; struct Matrix { ll a[2][2]; Matrix() {} Matrix(int x) { for (int i = 0; i < 2; i++) for (int j = 0; j < 2; j++) a[i][j] = i==j ? x : 0; } Matrix operator * (const Matrix &x) { Matrix res; for (int i = 0; i < 2; i ++) { for (int j = 0; j < 2; j++) { res.a[i][j] = 0; for (int k = 0; k < 2; k++) { res.a[i][j] = (res.a[i][j]+a[i][k]*x.a[k][j])%MOD; } } } return res; } inline ll sum() { return (a[0][0] + a[0][1] + a[1][0] + a[1][1])%MOD; } inline void update(int i, int j) { a[i][j] ^= 1; } inline void init() { a[0][0] = a[0][1] = a[1][0] = a[1][1] = 1; } void output() { puts("Matrix: "); for (int i = 0; i < 2; i ++) { for (int j = 0; j < 2; j++) printf("%I64d ", a[i][j]); puts(""); } } }; Matrix a[MAXN<<2]; int id[MAXN]; #define LS l, m, p<<1 #define RS m+1, r, p<<1|1 inline void pushUp(int p) { a[p] = a[p<<1]*a[p<<1|1]; } void build(int l, int r, int p) { if (l==r) { a[p].init(); id[l] = p; return ; } int m = (l+r) >> 1; build(LS); build(RS); pushUp(p); } void update(int p, int i, int j) { p = id[p]; a[p].update(i, j); p >>= 1; while (p>0) { pushUp(p); p >>= 1; } } Matrix query(int L, int R, int l, int r, int p) { if (L<=l&&r<=R) return a[p]; int m = (l+r)>>1; Matrix res(1); if (L<=m) res = res * query(L, R, LS); if (m <R) res = res * query(L, R, RS); return res; } int main() { #ifdef Phantom01 freopen("1003.txt", "r", stdin); #endif //Phantom01 int n, m; int op, x, y, z; while (scanf("%d%d", &n, &m)!=EOF) { n--; build(1, n, 1); while (m--) { scanf("%d", &op); if (op==0) { scanf("%d%d", &x, &y); y--; printf("%I64d\n", query(x, y, 1, n, 1).sum()); } else { scanf("%d%d%d", &x, &y, &z); y--; z--; update(x, y, z); } } } return 0; }
View Code
相关文章推荐
- HDU 5068 Harry And Math Teacher (矩阵处理,线段树)
- HDU 5068 Harry And Math Teacher 线段树维护矩阵乘积
- hdu 5068 Harry And Math Teacher 线段树
- HDU 5068 Harry And Math Teacher
- hdu 5068 Harry And Math Teacher ( 线段树+矩阵乘法 )
- HDU 5068 Harry And Math Teacher
- HDU-5068-Harry And Math Teacher(线段树)
- hdu 5068 Harry And Math Teacher(BestCoder Round #14)
- 【线段树】 HDOJ 5068 Harry And Math Teacher
- hdu 5069 Harry And Biological Teacher
- HDU 5069 Harry And Biological Teacher(fail树+线段树优化)
- 【HDU5068】Harry And Math Teacher
- hdu 5066 Harry And Physical Teacher(Bestcoder Round #14)
- hdu 5066 Harry And Physical Teacher(Bestcoder Round #14)
- hdu5066——Harry And Physical Teacher(物理)
- HDU 5066 Harry And Physical Teacher(物理题)
- BestCoder Round #14 03 Harry And Math Teacher (线段树)
- HDU 5066 Harry And Physical Teacher
- hdu 5066 Harry And Physical Teacher(物理题 弹性碰撞)
- HDU 5066 Harry And Physical Teacher