WA 的一声就哭了出来
查看原帖
WA 的一声就哭了出来
726139
残阳如血楼主2024/5/12 21:04

WA 了,样例也过不去。

#include <vector>
#include <iostream>
const int N = 1e5 + 10;
const int MOD = 1e9 + 7;
typedef long long lint;

template <typename T> // T 表示矩阵存的值的类型
struct Matrix {
	size_t n, m; // n 为行数,m 为列数
	std::vector<std::vector<T>> a;
	Matrix(size_t _n = 0, size_t _m = 0) : n(_n), m(_m) {
		a.resize(_n);
		for (size_t i = 0; i < _n; ++i)
			a[i].resize(_m);
	}
  Matrix(const std::vector<std::vector<T>> &_a) : n(_a.size()), m(_a[0].size()), a(_a) {}
  void build() {
    if (n != m) throw "This matrix can't be a I";
    for (size_t i = 0; i < n; ++i) a[i][i] = 1;
  }
  void clear() { for (auto &x : a) for (auto &y : x) y = 0; }
  bool empty() const {
    for (size_t i = 0; i < n; ++i)
      for (size_t j = 0; j < m; ++j) {
        if ((i == j && a[i][j] != 1) || (i != j && a[i][j != 0]))
          return false;
      }
    return true;
  }
  Matrix<T> operator=(const Matrix<T> &A) {
    a = A.a, n = A.a.size(), m = A.a[0].size();
    return *this;
  }
  Matrix<T> operator+(const Matrix<T> &A) const {
    if (n != A.n || m != A.m) throw "The Matrixes can't plus.";
    Matrix<T> res(n, m);
    for (size_t i = 0; i < n; ++i)
      for (size_t j = 0; j < m; ++j)
        res.a[i][j] = (a[i][j] + A.a[i][j]) % MOD;
    return res;
  }
  void operator+=(const Matrix<T> &A) {
    *this = *this + A;
  }
	Matrix<T> operator*(const Matrix<T> &A) const {
		if (m != A.n) throw "The Matrixes can't mul.";
		Matrix<T> res(n, A.m);
		for (size_t i = 0; i < n; ++i) // 枚举最终矩阵的行
			for (size_t j = 0; j < A.m; ++j) // 枚举最终矩阵的列
				for (size_t k = 0; k < m; ++k) // 枚举 A 的列(B 的行)
					(res.a[i][j] += a[i][k] * A.a[k][j]) %= MOD; // 实际实现中可能需要取模
		return res;
	}
  void operator*=(const Matrix<T> &A) {
    *this = *this * A;
  }
  friend std::istream &operator>>(std::istream &is, Matrix<T> &A) { // 读入矩阵
    for (size_t i = 0; i < A.n; ++i)
      for (size_t j = 0; j < A.m; ++j)
        is >> A.a[i][j];
    return is;
  }
  friend std::ostream &operator<<(std::ostream &os, const Matrix<T> &A) { // 输出矩阵
    for (size_t i = 0; i < A.n; ++i) {
      for (size_t j = 0; j < A.m; ++j)
        os << A.a[i][j] << ' ';
      os << '\n';
    }
    return os;
  }
  Matrix<T> qpow(size_t b) const { // 矩阵快速幂
    if (n != m) throw "This matrix can't qpow.";
    Matrix<T> ans(n, m), P = *this;
    ans.build();
    for (; b; b >>= 1) {
      if (b & 1) ans *= P;
      P *= P;
    }
    return ans;
  }
};

template <typename T>
struct Pool { // 内存池
  std::vector<T *> buf;
  T *create() {
    buf.push_back(new T);
    return buf.back();
  }
  void dispose() {
    for (size_t i = 0; i < buf.size(); ++i) delete buf[i];
    buf.clear();
  }
};

struct TreeNode { // 线段树节点
  int l, r;
  Matrix<lint> w, lzy;
  TreeNode *lson, *rson;
};

int n, m, a[N];
Pool<TreeNode> p;
const Matrix<lint> A(std::vector<std::vector<lint>>({{1}, {1}})); // 斐波那契的初始矩阵
const Matrix<lint> P(std::vector<std::vector<lint>>({{0, 1}, {1, 1}})); // 斐波那契的转移矩阵

bool inRange(TreeNode *u, int L, int R) { return u->l >= L && u->r <= R; }
bool outRange(TreeNode *u, int L, int R) { return u->l > R || u->r < L; }

void maketag(TreeNode *u, const Matrix<lint> &x) { u->w = x * u->w, u->lzy = x * u->lzy; }
void pushup(TreeNode *u) { u->w = u->lson->w + u->rson->w; }
void pushdown(TreeNode *u) {
  if (u->lzy.empty()) return ;
  maketag(u->lson, u->lzy);
  maketag(u->rson, u->lzy);
  u->lzy.build();
}

TreeNode *build(int l, int r) { // 建树
  TreeNode *u = p.create();
  u->l = l, u->r = r;
  u->lzy = Matrix<lint>(2, 2);
  u->lzy.build();
  if (l == r) {
    if (a[l] <= 2) u->w = A;
    else u->w = P.qpow(a[l] - 2) * A;
    u->lson = u->rson = nullptr;
    return u;
  }
  int mid = l + r >> 1;
  u->lson = build(l, mid);
  u->rson = build(mid + 1, r);
  pushup(u);
  return u;
}

Matrix<lint> query(TreeNode *u, int L, int R) {
  if (outRange(u, L, R)) return Matrix<lint>(2, 1);
  if (inRange(u, L, R)) return u->w;
  pushdown(u);
  auto m1 = query(u->lson, L, R);
  auto m2 = query(u->rson, L, R);
  return m1 + m2;
}

void update(TreeNode *u, int L, int R, const Matrix<lint> &x) {
  if (outRange(u, L, R)) return ;
  if (inRange(u, L, R)) { maketag(u, x); return ; }
  pushdown(u);
  update(u->lson, L, R, x);
  update(u->rson, L, R, x);
  pushup(u);
}

int main() {
  // freopen("sample.in", "r", stdin);
  // std::cin.tie(0)->sync_with_stdio(0);
  std::cin >> n >> m;
  for (int i = 1; i <= n; ++i) std::cin >> a[i];
  TreeNode *root = build(1, n);
  for (int op, l, r, x; m; --m) {
    std::cin >> op >> l >> r;
    if (op == 1) std::cin >> x, update(root, l, r, P.qpow(x));
    else std::cout << query(root, l, r).a[1][0] << '\n';
  }
  std::cout.flush();
  return 0;
}
2024/5/12 21:04
加载中...