zoukankan      html  css  js  c++  java
  • Codeforces 719 E. Sasha and Array (线段树+矩阵运算)

    题目链接:http://codeforces.com/contest/719/problem/E

    题意:操作1将[l, r] + x;

            操作2求f[l] + ... + f[r];

    题解:注意矩阵可以是a*(b + c) = a*b + a*c ,还有update的时候传入矩阵

      1 //#pragma comment(linker, "/STACK:102400000, 102400000")
      2 #include <algorithm>
      3 #include <iostream>
      4 #include <cstdlib>
      5 #include <cstring>
      6 #include <cstdio>
      7 #include <vector>
      8 #include <cmath>
      9 #include <ctime>
     10 #include <list>
     11 #include <set>
     12 #include <map>
     13 using namespace std;
     14 typedef long long LL;
     15 typedef pair <int, int> P;
     16 const int N = 1e5 + 5;
     17 LL a[N], mod = 1e9 + 7;
     18 struct data {
     19     LL mat[3][3];
     20     data() {
     21         mat[1][1] = mat[2][1] = mat[1][2] = 1;
     22         mat[2][2] = 0;
     23     }
     24     void init() {
     25         mat[1][1] = mat[2][2] = 1;
     26         mat[1][2] = mat[2][1] = 0;
     27     }
     28 }op;
     29 struct SegTree {
     30     int l, r;
     31     data lazy;
     32     data val;  
     33 }T[N << 2];
     34 
     35 data operator +(const data &a, const data &b) {
     36     data ans;
     37     for(int i = 1; i <= 2; ++i) {
     38         for(int j = 1; j <= 2; ++j) {
     39             ans.mat[i][j] = (a.mat[i][j] + b.mat[i][j]) % mod;
     40         }
     41     }
     42     return ans;
     43 }
     44 
     45 data operator *(const data &a, const data &b) {
     46     data ans;
     47     for(int i = 1; i <= 2; ++i) {
     48         for(int j = 1; j <= 2; ++j) {
     49             ans.mat[i][j] = 0;
     50             for(int k = 1; k <= 2; ++k) {
     51                 ans.mat[i][j] = (ans.mat[i][j] + a.mat[i][k] * b.mat[k][j] % mod) % mod;
     52             }
     53         }
     54     }
     55     return ans;
     56 }
     57 
     58 data operator ^(data a, LL n) {
     59     data ans;
     60     for(int i = 1; i <= 2; ++i) {
     61         for(int j = 1; j <= 2; ++j) {
     62             ans.mat[i][j] = (i == j);
     63         }
     64     }
     65     while(n) {
     66         if(n & 1)
     67             ans = ans * a;
     68         a = a * a;
     69         n >>= 1;
     70     }
     71     return ans;
     72 }
     73 
     74 bool cmp(const data &a) {
     75     for(int i = 1; i <= 2; ++i) {
     76         for(int j = 1; j <= 2; ++j) {
     77             if(a.mat[i][j] != op.mat[i][j])
     78                 return false;
     79         }
     80     }
     81     return true;
     82 }
     83 
     84 inline void pushdown(int p) {
     85     if(!cmp(T[p].lazy)) {
     86         T[p << 1].lazy = T[p].lazy * T[p << 1].lazy;
     87         T[(p << 1)|1].lazy = T[p].lazy * T[(p << 1)|1].lazy;
     88         T[p << 1].val = T[p << 1].val * T[p].lazy;
     89         T[(p << 1)|1].val = T[(p << 1)|1].val * T[p].lazy;
     90         T[p].lazy.init();
     91     }
     92 }
     93 
     94 void build(int p, int l, int r) {
     95     int mid = (l + r) >> 1;
     96     T[p].l = l, T[p].r = r, T[p].lazy.init();
     97     if(l == r) {
     98         scanf("%lld", a + l);
     99         T[p].val = T[p].val ^ (a[l] - 1);
    100         return ;
    101     }
    102     build(p << 1, l, mid);
    103     build((p << 1)|1, mid + 1, r);
    104     T[p].val = T[p << 1].val + T[(p << 1)|1].val;
    105 }
    106 
    107 void update(int p, int l, int r, data add) {
    108     int mid = (T[p].l + T[p].r) >> 1;
    109     if(T[p].l == l && T[p].r == r) {
    110         T[p].lazy = add * T[p].lazy;
    111         T[p].val = T[p].val * add;
    112         return ;
    113     }
    114     pushdown(p);
    115     if(r <= mid) {
    116         update(p << 1, l, r, add);
    117     } else if(l > mid) {
    118         update((p << 1)|1, l, r, add);
    119     } else {
    120         update(p << 1, l, mid, add);
    121         update((p << 1)|1, mid + 1, r, add);
    122     }
    123     T[p].val = T[p << 1].val + T[(p << 1)|1].val;
    124 }
    125 
    126 LL query(int p, int l, int r) {
    127     int mid = (T[p].l + T[p].r) >> 1;
    128     if(T[p].l == l && T[p].r == r) {
    129         return T[p].val.mat[1][1];
    130     }
    131     pushdown(p);
    132     if(r <= mid) {
    133         return query(p << 1, l, r);
    134     } else if(l > mid) {
    135         return query((p << 1)|1, l, r);
    136     } else {
    137         return (query(p << 1, l, mid) + query((p << 1)|1, mid + 1, r)) % mod;
    138     }
    139 }
    140 
    141 int main()
    142 {
    143     op.init();
    144     int n, m;
    145     scanf("%d %d", &n, &m);
    146     build(1, 1, n);
    147     int c, l, r;
    148     LL add;
    149     while(m--) {
    150         scanf("%d %d %d", &c, &l, &r);
    151         if(c == 1) {
    152             scanf("%lld", &add);
    153             data temp;
    154             update(1, l, r, temp ^ add);
    155         } else {
    156             printf("%lld
    ", query(1, l, r));
    157         }
    158     }
    159     return 0;
    160 }
  • 相关阅读:
    python+opencv实现图像自适应阈值的均衡化
    ubuntu添加新的分辨率选项(干货)
    python+opencv检测图像清晰度
    python根据列表创建文件夹,拷贝指定文件
    牛客多校Round 4
    牛客多校Round 3
    HDU多校Round 2
    HDU多校Round 1
    牛客多校Round 2
    牛客多校Round 1
  • 原文地址:https://www.cnblogs.com/Recoder/p/5904442.html
Copyright © 2011-2022 走看看