codeforces 373div1 Sasha and Array 矩阵+线段树

来源:互联网 发布:淘宝低价销售的危害 编辑:程序博客网 时间:2024/05/21 08:46

用线段树储存价值和,因为矩阵 a1 * b + a2 * b + a3 * b + a4 * b + a5 * b = (a1 + a2 + a3 + a4 + a5) * b;
然后进行下优化,尽量减少快速幂的运算数量

#include<cstdio>#include<algorithm>#include<iostream>#include<cstring>#define lson i<<1#define rson (i<<1) + 1#define maxn 100005#define LL long longusing namespace std;int n,k,b,m;LL mod = 1000000007ll;//快速幂struct ma{     int m[2][2],row,col;     ma()     {         memset(m,0,sizeof(m));         row = col = 0;     }     ma operator * (ma ma1) //乘     {        ma ans;        ans.row = row;        ans.col = ma1.col;        for(int i = 0;i < ans.row;i++)            for(int j = 0;j < ans.col;j++)            {                for(int k = 0;k < col;k++)                {                    ans.m[i][j] = (ans.m[i][j] + ((LL)m[i][k] * ma1.m[k][j])) % mod;                }            }        return ans;     }     ma operator + (ma ma1) //加     {         ma ans;         ans.row = row;         ans.col = col;         for(int i = 0;i < row;i++)             for(int j = 0;j < col;j++)                 {                    ans.m[i][j] =  ma1.m[i][j] + m[i][j];                    ans.m[i][j] %= mod;                 }          return  ans;     }     ma operator^(int n)  // 快速幂     {         ma ans,ma1;         ans.row = row; ans.col = col;         for(int i = 0;i < row;i++)             ans.m[i][i] = 1;         ma1.row = row;  ma1.col = col;         for(int i = 0;i < row;i++)             for(int j = 0;j < col;j++)                  ma1.m[i][j] = m[i][j];         while(n)         {            if(n&1)ans = ans * ma1;            ma1 = ma1 * ma1;            n >>= 1;         }         return ans;     }}E, mul;ma va[maxn * 4], add[maxn * 4];void pushUp(int i){     va[i]  = va[lson] + va[rson];}void pushDown(int i){    va[lson] = va[lson] * add[i];    va[rson] = va[rson] * add[i];    add[lson] = add[lson] * add[i];    add[rson] = add[rson] * add[i];    add[i] = E;}void build(int i, int l, int r){     add[i] = E;     if(l == r)     {        int pre;        scanf("%d", &pre);        pre--;        va[i] = mul ^ pre;        return;     }     int mid = (l + r) / 2;     build(lson , l, mid);     build(rson , mid + 1, r);     pushUp(i);}void update(int i, int l, int r, int L , int R, ma ADD){     if(l == L && r == R)     {          va[i] = va[i] * ADD;          add[i] = add[i] * ADD;          return;     }     pushDown(i);     int mid = (l + r) / 2;     if(R <= mid) update(lson, l, mid, L, R, ADD);     else if(L > mid) update(rson, mid + 1, r, L, R, ADD);     else{         update(lson, l, mid, L , mid, ADD);         update(rson, mid + 1, r, mid + 1, R, ADD);     }     pushUp(i);}int query(int i, int l, int r, int L, int R){     if(l == L && r == R)     {          return va[i].m[0][0];     }     pushDown(i);     int mid = (l + r) / 2;     if(R <= mid) return query(lson, l, mid, L , R);     else if(L > mid) return query(rson, mid + 1, r, L, R);     else{         return (query(lson, l, mid, L , mid) + query(rson, mid + 1, r, mid + 1, R))%mod;     }}int main(){    E.row = 2, E.col = 2;    E.m[0][0] = 1, E.m[0][1] = 0;    E.m[1][0] = 0, E.m[1][1] = 1;    mul.row = 2, mul.col = 2;    mul.m[0][0] = 1, mul.m[0][1] = 1;    mul.m[1][0] = 1, mul.m[1][1] = 0;    scanf("%d%d", &n,&m);    build(1, 1, n);    while(m--)    {       int flag;       scanf("%d", &flag);       int a, b, c;       if(flag == 1){          scanf("%d%d%d", &a, &b, &c);          ma ADD = (mul ^ c);          update(1, 1, n, a, b, ADD);       }       else {          scanf("%d%d", &a,&b);          printf("%d\n", query(1, 1, n, a, b));       }    }    return 0;}
0 0
原创粉丝点击