Alex_tz307

Task Fibonacci Machine (fib)

Apr 6th, 2021 (edited)
281
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.99 KB | None | 0 0
  1. /// https://szkopul.edu.pl/problemset/problem/ii2ZJ7WanCQE4DykUbqLIyVb/site/?key=statement
  2. #include <bits/stdc++.h>
  3. #define vi vector<int>
  4. #define vvi vector<vi>
  5. #define vvvi vector<vvi>
  6.  
  7. using namespace std;
  8. using int64 = long long;
  9.  
  10. void fastIO() {
  11.   ios_base::sync_with_stdio(false);
  12.   cin.tie(nullptr);
  13.   cout.tie(nullptr);
  14. }
  15.  
  16. const int mod = 1e9 + 7;
  17.  
  18. void add_self(int &a, int b) {
  19.   a += b;
  20.   if (a >= mod)
  21.     a -= mod;
  22. }
  23.  
  24. vvi matrix_mult(const vvi &a, const vvi &b) {
  25.   vvi sol(2, vi(2));
  26.   for (int i = 0; i < 2; ++i)
  27.     for (int j = 0; j < 2; ++j)
  28.       for (int k = 0; k < 2; ++k)
  29.         add_self(sol[i][j], (int64)a[i][k] * b[k][j] % mod);
  30.   return sol;
  31. }
  32.  
  33. vi vector_mult(const vi &a, const vvi &b) {
  34.   vi sol(2);
  35.   for (int i = 0; i < 2; ++i)
  36.     for (int k = 0; k < 2; ++k)
  37.       add_self(sol[i], (int64)a[k] * b[i][k] % mod);
  38.   return sol;
  39. }
  40.  
  41. vvvi powers;
  42.  
  43. struct SegTree {
  44.   int Size;
  45.   vvi tree;
  46.   vi lazy;
  47.  
  48.   SegTree(int N) {
  49.     Size = 1;
  50.     while (Size < N)
  51.       Size <<= 1;
  52.     tree = vvi(Size << 1 | 1, vi(2));
  53.     lazy.resize(Size << 1 | 1);
  54.   }
  55.  
  56.   void build(int x, int lx, int rx) {
  57.     if (lx == rx) {
  58.       tree[x] = {0, 1};
  59.       return;
  60.     }
  61.     int mid = (lx + rx) >> 1;
  62.     build(x << 1, lx, mid);
  63.     build(x << 1 | 1, mid + 1, rx);
  64.     for (int i = 0; i < 2; ++i)
  65.       tree[x][i] = (tree[x << 1][i] + tree[x << 1 | 1][i]) % mod;
  66.   }
  67.  
  68.   void propagate(int x, int lx, int rx) {
  69.     if (lx == rx || lazy[x] == 0)
  70.       return;
  71.     for (int i = 0; i < 2; ++i) {
  72.       tree[x << 1 | i] = vector_mult(tree[x << 1 | i], powers[lazy[x]]);
  73.       lazy[x << 1 | i] += lazy[x];
  74.     }
  75.     lazy[x] = 0;
  76.   }
  77.  
  78.   void update(int x, int lx, int rx, int st, int dr) {
  79.     if (st <= lx && rx <= dr) {
  80.       tree[x] = vector_mult(tree[x], powers[1]);
  81.       ++lazy[x];
  82.       return;
  83.     }
  84.     int mid = (lx + rx) >> 1;
  85.     propagate(x, lx, rx);
  86.     if (st <= mid)
  87.       update(x << 1, lx, mid, st, dr);
  88.     if (mid < dr)
  89.       update(x << 1 | 1, mid + 1, rx, st, dr);
  90.     for (int i = 0; i < 2; ++i)
  91.       tree[x][i] = (tree[x << 1][i] + tree[x << 1 | 1][i]) % mod;
  92.   }
  93.  
  94.   int query(int x, int lx, int rx, int st, int dr) {
  95.     if (st <= lx && rx <= dr)
  96.       return tree[x][0];
  97.     int mid = (lx + rx) >> 1, ans1 = 0, ans2 = 0;
  98.     propagate(x, lx, rx);
  99.     if (st <= mid)
  100.       ans1 = query(x << 1, lx, mid, st, dr);
  101.     if (mid < dr)
  102.       ans2 = query(x << 1 | 1, mid + 1, rx, st, dr);
  103.     return (ans1 + ans2) % mod;
  104.   }
  105. };
  106.  
  107. void solve() {
  108.   int N, Q;
  109.   cin >> N >> Q;
  110.   SegTree tree(N);
  111.   tree.build(1, 1, N);
  112.   powers.resize(Q + 1);
  113.   powers[1] = {{0, 1}, {1, 1}};
  114.   for (int i = 2; i <= Q; ++i)
  115.     powers[i] = matrix_mult(powers[i - 1], powers[1]);
  116.   for (int q = 0; q < Q; ++q) {
  117.     char type;
  118.     int l, r;
  119.     cin >> type >> l >> r;
  120.     if (type == 'D')
  121.       tree.update(1, 1, N, l, r);
  122.     else cout << tree.query(1, 1, N, l, r) << '\n';
  123.   }
  124. }
  125.  
  126. int main() {
  127.   fastIO();
  128.   solve();
  129.   return 0;
  130. }
  131.  
Add Comment
Please, Sign In to add comment