Code forces 718C - Sasha and Array 线段树维护矩阵
谢谢YB。
1 #include <cstdio> 2 typedef long long ll; 3 const int mod=1e9+7; 4 struct Matrix { 5 int a[4]; 6 Matrix () { 7 for (int i=0;i<4;i++) 8 a[i]=0; 9 } 10 void init() { 11 a[0]=a[3]=1; 12 a[1]=a[2]=0; 13 } 14 Matrix operator + (const Matrix &B) const { 15 Matrix C; 16 for (int i=0;i<4;i++) 17 C.a[i]=(a[i]+B.a[i])%mod; 18 return C; 19 } 20 Matrix operator += (const Matrix &B) { 21 return *this=*this+B; 22 } 23 Matrix operator * (const Matrix &B) const { 24 Matrix C; 25 C.a[0]=((ll)a[0]*B.a[0]+(ll)a[1]*B.a[2])%mod; 26 C.a[1]=((ll)a[0]*B.a[1]+(ll)a[1]*B.a[3])%mod; 27 C.a[2]=((ll)a[2]*B.a[0]+(ll)a[3]*B.a[2])%mod; 28 C.a[3]=((ll)a[2]*B.a[1]+(ll)a[3]*B.a[3])%mod; 29 return C; 30 } 31 Matrix operator *=(const Matrix &B) { 32 return *this=*this*B; 33 } 34 Matrix operator ^ (int n) const { 35 Matrix C,x=*this; 36 C.init(); 37 while (n) { 38 if (n&1) 39 C*=x; 40 x*=x; 41 n>>=1; 42 } 43 return C; 44 } 45 void write() { 46 for (int i=0;i<4;i++) 47 printf("%d%c",a[i]," \n"[i%2==1]); 48 } 49 }; 50 const int maxn=1e5+10; 51 Matrix b,f,T[maxn<<2],Lazy[maxn<<2]; 52 #define m ((l+r)>>1) 53 #define lc o<<1 54 #define rc lc|1 55 void build(int o,int l,int r) { 56 Lazy[o].init(); 57 if (l==r) { 58 int x; 59 scanf("%d",&x); 60 T[o]=b*(f^(x-1)); 61 } 62 else { 63 build(lc,l,m); 64 build(rc,m+1,r); 65 T[o]=T[lc]+T[rc]; 66 } 67 } 68 void pushdown(int o) { 69 T[o]*=Lazy[o]; 70 Lazy[lc]*=Lazy[o]; 71 Lazy[rc]*=Lazy[o]; 72 Lazy[o].init(); 73 } 74 void modify(int o,int l,int r,int ql,int qr,const Matrix &fn) { 75 if (r-l) 76 pushdown(o); 77 if (ql<=l&&r<=qr) 78 Lazy[o]*=fn; 79 else { 80 if (ql<=m) modify(lc,l,m,ql,qr,fn); 81 if (m<qr) modify(rc,m+1,r,ql,qr,fn); 82 T[o]=(T[lc]*Lazy[lc])+(T[rc]*Lazy[rc]); 83 } 84 } 85 int query(int o,int l,int r,int ql,int qr) { 86 if (r-l) 87 pushdown(o); 88 if (ql<=l&&r<=qr) 89 return (T[o]*Lazy[o]).a[0]; 90 else { 91 int ret=0; 92 if (ql<=m) 93 ret=(ret+query(lc,l,m,ql,qr))%mod; 94 if (m<qr) 95 ret=(ret+query(rc,m+1,r,ql,qr))%mod; 96 return ret; 97 } 98 } 99 int n,q; 100 int main() { 101 b.a[0]=1; 102 f.a[0]=f.a[1]=f.a[2]=1; 103 while (~scanf("%d%d",&n,&q)) { 104 build(1,1,n); 105 while (q--) { 106 int tp,l,r,x; 107 scanf("%d%d%d",&tp,&l,&r); 108 if (tp&1) { 109 scanf("%d",&x); 110 modify(1,1,n,l,r,f^x); 111 } 112 else 113 printf("%d\n",query(1,1,n,l,r)); 114 } 115 } 116 return 0; 117 }