代数递推关系可以用矩阵乘法处理
区间覆盖
*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+