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 }
View Code

 

posted @ 2016-09-28 19:38  Apiec  阅读(204)  评论(0编辑  收藏  举报