求调。
  • 板块学术版
  • 楼主FunKingDoor
  • 当前回复4
  • 已保存回复4
  • 发布时间2023/3/29 20:20
  • 上次更新2023/10/23 20:05:48
查看原帖
求调。
748854
FunKingDoor楼主2023/3/29 20:20
#include <iostream>
using namespace std;

namespace Matr {
	const int MX = 105;
	const int mod = 1e9 + 7;
	struct Matrix {
		int a[MX][MX];
		int N, M;
		void init() {
			for(int i = 1; i <= N; i++)
				for(int j = 1; j <= M; j++)
					a[i][j] = 0;
		}
		Matrix operator * (const Matrix &t) const {
			Matrix res;
			res.N = N;
			res.M = t.M;
			res.init();
			for(int k = 1; k <= M; k++) {
				for(int i = 1; i <= N; i++) {
					for(int j = 1; j <= t.M; j++) {
						res.a[i][j] += a[i][k] * t.a[k][j] % mod;
						res.a[i][j] %= mod;
					}
				}
			}
			return res;
		}
		bool operator == (const Matrix &t) const {
			if(N != t.N || M != t.M) return false;
			for(int i = 1; i <= N; i++)
				for(int j = 1; j <= M; j++)
					if(a[i][j] != t.a[i][j])
						return false;
			return true;
		}
		Matrix operator + (const Matrix &t) const {
			Matrix res;
			res.N = N;
			res.M = M;
			for(int i = 1; i <= N; i++)
				for(int j = 1; j <= M; j++)
					res.a[i][j] = a[i][j] + t.a[i][j];
			return res;
		}
		void read(int n, int m) {
			N = n;
			M = m;
			init();
			for(int i = 1; i <= n; i++)
				for(int j = 1; j <= m; j++)
					cin >> a[i][j];
		}
		void output() {
			for(int i = 1; i <= N; i++) {
				for(int j = 1; j <= M; j++)
					cout << a[i][j] << ' ';
				cout << endl;
			}
		}
	};
	Matrix dwjz(int n) {
		Matrix tmp;
		tmp.init();
		tmp.N = n;
		tmp.M = n;
		for(int i = 1; i <= n; i++)
			tmp.a[i][i] = 1;
		return tmp;
	}
	Matrix jzksm(Matrix Ma, int b) {
		Matrix res = dwjz(Ma.N);
		while(b) {
			if(b & 1) res = res * Ma;
			Ma = Ma * Ma;
			b >>= 1;
		}
		return res;
	}
}

using namespace Matr;

Matrix base, dw, modu;

struct node {
	int left, right;
	Matrix lazy, sum;
}t[200005];

void update(int id) {
	t[id].sum = t[id << 1].sum * t[id << 1].lazy + t[id << 1 | 1].sum + t[id << 1 | 1].lazy;
}

void pushdown(int id) {
	if(!(t[id].lazy == dw)) {
		t[id << 1].lazy = t[id << 1].lazy * t[id].lazy;
		t[id << 1 | 1].lazy = t[id << 1 | 1].lazy * t[id].lazy;
		update(id);
		t[id].lazy = dw;
	}
}

void buildtree(int id, int l, int r) {
	t[id].left = l;
	t[id].right = r;
	t[id].lazy = dw;
	if(l == r) {
		int tmp;
		cin >> tmp;
		t[l].sum = modu * jzksm(base, tmp - 2);
		return;
	}
	int mid = (l + r) >> 1;
    buildtree(id << 1, l, mid);
    buildtree(id << 1 | 1, mid + 1, r);
    update(id);
}

void change(int id, int l, int r, int c) {
	if(t[id].left == l && t[id].right == r) {
		t[id].lazy = t[id].lazy * jzksm(base, c - 1);
		return;
	}
	pushdown(id);
	if(r <= t[id << 1].right)
		change(id << 1, l, r, c);
	else if(t[id << 1 | 1].left <= l)
		change(id << 1 | 1, l, r, c);
	else {
		change(id << 1, l, t[id << 1].right, c);
		change(id << 1 | 1, t[id << 1 | 1].left, r, c);
	}
	update(id);
}

Matrix query(int id, int l, int r) {
	if(t[id].left == l && t[id].right == r)
		return t[id].sum * t[id].lazy;
	pushdown(id);
	if(r <= t[id << 1].right) 
		return query(id << 1, l, r);
	else if(t[id << 1 | 1].left <= l) 
		return query(id << 1 | 1, l, r);
	else 
		return query(id << 1, l, t[id << 1].right) + query(id << 1 | 1, t[id << 1 | 1].left, r);
}

int main() {
	modu.N = 1;
	modu.M = 2;
	modu.a[1][1] = modu.a[1][2] = 1;
	base.N = base.M = 2;
	base.a[1][1] = base.a[1][2] = base.a[2][1] = 1;
	base.a[2][2] = 0;
	dw = dwjz(2);
	int n, m;
	cin >> n >> m;
	buildtree(1, 1, n);
	while(m--) {
		int op;
		cin >> op;
		if(op == 1) {
			int l, r, c;
			cin >> l >> r >> c;
			change(1, l, r, c);
		} else {
			int l, r;
			cin >> l >> r;
			cout << query(1, l, r).a[1][1] << endl;
		}
	}
	
	return 0;
}

编译不成功。

2023/3/29 20:20
加载中...