zoukankan      html  css  js  c++  java
  • HDU 5068 Harry And Math Teacher

    Harry And Math Teacher

    链接

    题意:

      n层楼,每层有两扇门,初始时,从第i层到第i+1的所有门都可以相互到达。两种操作,询问从a层到b层的方案数,修改x层到x+1层两扇门之间的连通性。

    分析:

      线段树维护转移矩阵。

      考虑如歌计算a->b的方案数,$f[i][0/1]$表示从起点到第i层,当前在第j扇门时的方案数,那么$f[i][j]=f[i-1][0] imes a[0][j]+f[i-1][1] imes a[1][j]$,$a[][]$为i-1层到i层的联通性。

      然后发现如果将a看做一个矩阵的话,就是从a到b-1的所有矩阵乘起来。

      修改操作只是修改一个矩阵,所以可以线段树维护。

      a数组开了longlong就过了?感觉好像不需要开。

    代码:

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<cmath>
     6 #include<cctype>
     7 #include<set>
     8 #include<queue>
     9 #include<vector>
    10 #include<map>
    11 #define Root 1, n, 1
    12 #define lson l, mid, rt << 1
    13 #define rson mid + 1, r, rt << 1 | 1
    14 using namespace std;
    15 typedef long long LL;
    16 
    17 inline int read() {
    18     int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1;
    19     for(;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f;
    20 }
    21 
    22 const int N = 50005;
    23 const int mod = 1e9 + 7;
    24 
    25 struct Node{
    26     LL a[2][2];
    27     Node() { memset(a, 0, sizeof(a)); }
    28 }T[N << 2]; 
    29 
    30 Node operator + (const Node &A,const Node &B) {
    31     Node C;
    32     for (int k = 0; k < 2; ++k)
    33         for (int i = 0; i < 2; ++i) 
    34             for (int j = 0; j < 2; ++j) {
    35                 C.a[i][j] += (1ll * A.a[i][k] * B.a[k][j]) % mod;
    36                 if (C.a[i][j] >= mod) C.a[i][j] -= mod;
    37             }
    38     return C;
    39 }
    40 void build(int l,int r,int rt) {
    41     if (l == r) {
    42         T[rt].a[0][0] = T[rt].a[0][1] = T[rt].a[1][0] = T[rt].a[1][1] = 1;
    43         return ;
    44     }
    45     int mid = (l + r) >> 1;
    46     build(lson); build(rson);
    47     T[rt] = T[rt << 1] + T[rt << 1 | 1];
    48 }
    49 void update(int l,int r,int rt,int p,int x,int y) {
    50     if (l == r) {
    51         T[rt].a[x][y] ^= 1; return ;
    52     }
    53     int mid = (l + r) >> 1;
    54     if (p <= mid) update(lson, p, x, y);
    55     else update(rson, p, x, y);
    56     T[rt] = T[rt << 1] + T[rt << 1 | 1];
    57 }
    58 Node query(int l,int r,int rt,int L,int R) {
    59     if (L <= l && r <= R) return T[rt];
    60     int mid = (l + r) >> 1;
    61     if (R <= mid) return query(lson, L, R);
    62     else if (L > mid) return query(rson, L, R);
    63     else return query(lson, L, R) + query(rson, L, R);
    64 }
    65 void solve(int n,int m) {
    66     build(Root);
    67     while (m --) {
    68         int opt = read();
    69         if (opt == 0) {
    70             int a = read(), b = read();
    71             Node ans = query(Root, a, b - 1);
    72             LL sum = (ans.a[0][0] + ans.a[0][1] + ans.a[1][0] + ans.a[1][1]) % mod;
    73             printf("%I64d
    ", sum);
    74         }
    75         else {
    76             int x = read(), y = read(), z = read();
    77             update(Root, x, y - 1, z - 1);
    78         }
    79     }
    80 }
    81 int main() {
    82     int n, m;
    83     while (~scanf("%d%d", &n, &m)) solve(n, m);
    84     return 0;
    85 }
  • 相关阅读:
    poj3673
    poj3438
    poj3461
    poj3518
    poj3672
    变秃了,也变强了!爆肝吐血整理出的超硬核JVM笔记分享!
    左手字节,右手阿里,我是如何通阿里架构师的java面试文档,拿到多家大厂offer的
    Java异常处理与常用类
    copy_{to, from}_user()的思考
    vi文本编辑器常用指令功能
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10104866.html
Copyright © 2011-2022 走看看