矩阵快速幂+区间覆盖

代数递推关系可以用矩阵乘法处理

区间覆盖

*1ll转换longlong防溢出

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=10000+10,mod=1e9+7;
struct one{
	ll pos;
	int p,f;
	bool operator < (const one & x) {return pos<x.pos;}
}a[maxn*3];
int cnt,n;
int m[3][3];
int c[3][3];
ll l,r,m1;
int f1;
void mul(int a1[3][3],int b[3][3])
{
	static  int c[3][3];
	memset(c,0,sizeof(c));
	for(int i=0;i<=2;++i)
	for(int j=0;j<=2;++j)
	for(int k=0;k<=2;++k)
	{
		c[i][j]=(c[i][j]+((1ll*a1[i][k]%mod)*(1ll*b[k][j]%mod))%mod)%mod;
	}
	memcpy(a1,c,sizeof(c));
}//矩阵乘法
int main ()
{
	scanf("%d%lld",&n,&m1);
	a[cnt].pos=2;
	a[cnt].p=0;
	a[cnt++].f=0;
	for(int i=0;i<n;++i)
	{
		scanf("%d%lld%lld",&f1,&l,&r);
		a[cnt].pos=l;
	    a[cnt].p=f1-1;
	    a[cnt++].f=1;
	    a[cnt].pos=r+1;
	    a[cnt].p=f1-1;
	    a[cnt++].f=-1;
	}
	a[cnt].pos=m1+1;//注意前后边界设置,不然会少前后两段
	a[cnt].p=0;
	a[cnt].f=0;
	sort(a,a+cnt+1);
	int r[3];
	r[0]=0,r[1]=0,r[2]=0;
	c[0][1]=1;
	for(int i=0;i<cnt;++i)
	{
		r[a[i].p]+=a[i].f;//区间标记覆盖,开始+1,结束-1
		memset(m,0,sizeof(m));
		if(!r[0])  m[0][0]=m[1][0]=1;
		if(!r[1])  m[0][1]=m[1][1]=m[2][1]=1;
		if(!r[2])  m[1][2]=m[2][2]=1;
		ll d=a[i+1].pos-a[i].pos;
		for(;d;d>>=1,mul(m,m))
		{
			if(d&1) mul(c,m);
		 } //矩阵乘法快速幂
	}
	printf("%lld",c[0][1]);
	return 0;
}

矩阵快速幂:https://blog.csdn.net/zhangxiaoduoduo/article/details/81807338

原题:https://codeforces.com/contest/954/problem/F

int:2e9+

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值