WA 0pts,样例都没过
查看原帖
WA 0pts,样例都没过
585657
lanxi楼主2023/12/6 20:12
#include <iostream>
#define int long long
using namespace std;
const int mod = 1e9+7;

struct Matrix
{
	int m[2][2];
	
	void init()
	{
		m[0][0] = m[1][1] = 1;
	}
	
	bool empty()
	{
		return m[0][0] == m[1][1]&&m[0][0] == 1&&m[0][1] == m[1][0]&&m[0][1] == 0;
	}
};
Matrix basic;

struct Tree
{
	Matrix tr;
	Matrix lz;
};
Tree tr[400001];
int a[100001];

Matrix operator + (const Matrix& x,const Matrix& y)
{
	Matrix ans;
	for(int i = 0;i <= 1;i++)
	{
		for(int j = 0;j <= 1;j++)
		{
			ans.m[i][j] = (x.m[i][j]+y.m[i][j])%mod;
		}
	}
	return ans;
}

Matrix operator * (const Matrix& x,const Matrix& y)
{
	Matrix ans;
	for(int i = 0;i <= 1;i++)
	{
		for(int j = 0;j <= 1;j++)
		{
			for(int k = 0;k <= 1;k++)
			{
				ans.m[i][j] += (x.m[i][k]*y.m[k][j])%mod;
				ans.m[i][j] %= mod;
			}
		}
	}
	return ans;
}

Matrix operator ^ (Matrix x,int y)
{
	Matrix ans;
	ans.init();
	while(y)
	{
		if(y%2 == 1)
		{
			ans = ans * x;
		}
		x = x * x;
		y /= 2;
	}
	return ans;
}

void push_down(int p)
{
	if (tr[p].lz.empty() == false)
	{
		tr[p*2].lz = tr[p*2].lz * tr[p].lz;
		tr[p*2+1].lz = tr[p*2+1].lz * tr[p].lz;
		tr[p*2].tr = tr[p*2].tr * tr[p].lz;
		tr[p*2+1].tr = tr[p*2+1].tr * tr[p].lz;
		tr[p].lz.init();
	}
}

void build_tree(int l,int r,int p)
{
	tr[p].lz.init();
	if(l == r)
	{
		if(a[l] == 1)
		{
			tr[p].tr.m[0][0] = 1;
		}
		else
		{
			tr[p].tr.m[0][0] = tr[p].tr.m[0][1] = 1;
		}
		if(a[l] > 2)
		{
			tr[p].tr = tr[p].tr * (basic ^ (a[l]-2));
		}
		return;
	}
	int mid = (l+r)/2;
	build_tree(l,mid,p*2);
	build_tree(mid+1,r,p*2+1);
	tr[p].tr = tr[p*2].tr + tr[p*2+1].tr;
}

void add(int l,int r,int s,int t,Matrix x,int p)
{
	if(s > r||l > t)
	{
		return;
	}
	if(s <= l&&r <= t)
	{
		tr[p].lz = tr[p].lz * x;
		tr[p].tr = tr[p].tr * x;
		return;
	}
	push_down(p);
	int mid = (l+r)/2;
	if(mid >= s)
	{
		add(l,mid,s,t,x,p*2);
	}
	if(mid+1 <= t)
	{
		add(mid+1,r,s,t,x,p*2+1);
	}
	tr[p].tr = tr[p*2].tr + tr[p*2+1].tr;
}

int sum(int l,int r,int s,int t,int p)
{
	if(s > r||l > t)
	{
		return 0;
	}
	if(s <= l&&r <= t)
	{
		return tr[p].tr.m[0][0];
	}
	push_down(p);
	int mid = (l+r)/2;
	int ans = 0;
	if(mid >= s)
	{
		ans += sum(l,mid,s,t,p*2);
		ans %= mod;
	}
	if(mid+1 <= t)
	{
		ans += sum(mid+1,r,s,t,p*2+1);
		ans %= mod;
	}
	tr[p].tr = tr[p*2].tr + tr[p*2+1].tr;
	return ans%mod;
}

signed main()
{
	basic.m[0][0] = basic.m[0][1] = basic.m[1][0] = 1;
	int n,m;
	scanf("%lld %lld",&n,&m);
	for(int i = 1;i <= n;i++)
	{
		scanf("%lld",&a[i]);
	}
	build_tree(1,n,1);
	for(int i = 1;i <= m;i++)
	{
		int op;
		scanf("%lld",&op);
		if(op == 1)
		{
			int l,r,x;
			scanf("%lld %lld %lld",&l,&r,&x);
			
			printf("%lld %lld\n%lld %lld\n\n",(basic ^ x).m[0][0],(basic ^ x).m[0][1],(basic ^ x).m[1][0],(basic ^ x).m[1][1]);
			
			add(1,n,l,r,basic ^ x,1);
		}
		else
		{
			int l,r;
			scanf("%lld %lld",&l,&r);
			printf("%lld\n",sum(1,n,l,r,1)%mod);
		}
	}
	return 0;
}

照着第三篇题解写的,不知道那里错了,求助

2023/12/6 20:12
加载中...