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 }
  • 相关阅读:
    .net开发微信(1)——微信订阅号的配置
    工作中EF遇到的问题
    .net Entity Framework初识1
    Razor视图
    jquery中利用队列依次执行动画
    .net找List1和List2的差集
    angularjs ng-if 中的ng-model 值作用域问题
    Spring Boot + JPA(hibernate 5) 开发时,数据库表名大小写问题
    springboot 启动排除某些bean 的注入
    angularjs 初始化方法执行两次以及url定义错误导致传值错误问题
  • 原文地址:https://www.cnblogs.com/mjtcn/p/10104866.html
Copyright © 2011-2022 走看看