Codeforces Round #373 (Div. 1) C.Sasha and Array

来源:互联网 发布:淘宝网原珍向天果官网 编辑:程序博客网 时间:2024/05/18 02:19

题目大意:给你一个长度为n的数列an,有两种操作

1、将L到R的ai加上X

2、询问L到R之间,f(aL)+f(aL+1)+……+f(aR)的和


考虑维护fib数列的转移

区间加,就相当于区间乘上一个矩阵

那么我们直接维护矩阵的合并和懒标记下推就可以了

乘的矩阵要预处理一下不然会多一个log的复杂度

#include<map>#include<cmath>#include<queue>#include<vector>#include<cstdio>#include<string>#include<cstring>#include<iostream>#include<algorithm>using namespace std;const int N=2;const long long MOD=1000000007;struct Matrix {long long grid[N][N];int row,col;Matrix():row(N),col(N){    memset(grid, 0, sizeof grid);  }  Matrix(int row, int col):row(row),col(col){    memset(grid, 0, sizeof grid);  }  Matrix operator *(const Matrix &b){    Matrix res(row, b.col);    for(int i = 0; i<res.row; i++)      for(int j = 0; j<res.col; j++)        for(int k = 0;k<col; k++)        res[i][j] = (res[i][j] + grid[i][k] * b.grid[k][j]) % MOD;  return res; } Matrix operator ^(long long exp){    Matrix res(row, col);    for(int i = 0; i < row; i++)res[i][i] = 1;    Matrix temp = *this;    for(; exp > 0; exp >>= 1, temp = temp * temp)      if(exp & 1) res = temp * res;    return res;  }  long long* operator[](int index){    return grid[index];  } void print(){    for(int i = 0; i <row; i++){      for(int j = 0; j < col-1; j++)        printf("%d ",grid[i][j]);      printf("%d\n",grid[i][col-1]);    }}};struct tree{int l,r;long long x[2];long long s[3][3];}tr[800001];inline long long cale(int d){Matrix c(2,2);if(d<=2&&d>0)return 1;if(d==0)return 0;c[0][0]=0;c[0][1]=1;c[1][0]=1;c[1][1]=1;if(d>2)c=c^(d-2);return (c[0][1]+c[1][1])%MOD;}int a[100001];inline void up(int p){tr[p].x[0]=(tr[p*2].x[0]+tr[p*2+1].x[0])%MOD;tr[p].x[1]=(tr[p*2].x[1]+tr[p*2+1].x[1])%MOD;}inline void push(int p){long long x0=tr[p*2].x[0],x1=tr[p*2].x[1];tr[p*2].x[0]=(x0*tr[p].s[1][1]+x1*tr[p].s[2][1])%MOD;tr[p*2].x[1]=(x0*tr[p].s[1][2]+x1*tr[p].s[2][2])%MOD;x0=tr[p*2+1].x[0],x1=tr[p*2+1].x[1];tr[p*2+1].x[0]=(x0*tr[p].s[1][1]+x1*tr[p].s[2][1])%MOD;tr[p*2+1].x[1]=(x0*tr[p].s[1][2]+x1*tr[p].s[2][2])%MOD;long long s11=tr[p*2].s[1][1],s12=tr[p*2].s[1][2],s21=tr[p*2].s[2][1],s22=tr[p*2].s[2][2];tr[p*2].s[1][1]=(s11*tr[p].s[1][1]+s12*tr[p].s[2][1])%MOD;tr[p*2].s[1][2]=(s11*tr[p].s[1][2]+s12*tr[p].s[2][2])%MOD;tr[p*2].s[2][1]=(s21*tr[p].s[1][1]+s22*tr[p].s[2][1])%MOD;tr[p*2].s[2][2]=(s21*tr[p].s[1][2]+s22*tr[p].s[2][2])%MOD;s11=tr[p*2+1].s[1][1],s12=tr[p*2+1].s[1][2],s21=tr[p*2+1].s[2][1],s22=tr[p*2+1].s[2][2];tr[p*2+1].s[1][1]=(s11*tr[p].s[1][1]+s12*tr[p].s[2][1])%MOD;tr[p*2+1].s[1][2]=(s11*tr[p].s[1][2]+s12*tr[p].s[2][2])%MOD;tr[p*2+1].s[2][1]=(s21*tr[p].s[1][1]+s22*tr[p].s[2][1])%MOD;tr[p*2+1].s[2][2]=(s21*tr[p].s[1][2]+s22*tr[p].s[2][2])%MOD;tr[p].s[1][1]=1;tr[p].s[1][2]=0;tr[p].s[2][1]=0;tr[p].s[2][2]=1;}inline void build(int p,int l,int r){tr[p].l=l;tr[p].r=r;if(l!=r){int mid=(l+r)/2;build(p*2,l,mid);build(p*2+1,mid+1,r);up(p);tr[p].s[1][1]=1;tr[p].s[1][2]=0;tr[p].s[2][1]=0;tr[p].s[2][2]=1;}else{tr[p].x[0]=cale(a[l]-1);tr[p].x[1]=cale(a[l]);tr[p].s[1][1]=1;tr[p].s[1][2]=0;tr[p].s[2][1]=0;tr[p].s[2][2]=1;} }inline long long query(int p,int l,int r){if(l<=tr[p].l&&tr[p].r<=r)return tr[p].x[1];else{push(p);int mid=(tr[p].l+tr[p].r)/2;long long ans=0;if(l<=mid)ans+=query(p*2,l,r);if(r>mid)ans+=query(p*2+1,l,r);ans=ans%MOD;return ans;}}Matrix c(2,2);long long xt[3][3];inline void change(int p,int l,int r,int x){if(l<=tr[p].l&&tr[p].r<=r){//c.print();long long x0=tr[p].x[0],x1=tr[p].x[1];tr[p].x[0]=(x0*c[0][0]+x1*c[1][0])%MOD;tr[p].x[1]=(x0*c[0][1]+x1*c[1][1])%MOD;long long s11=tr[p].s[1][1],s12=tr[p].s[1][2],s21=tr[p].s[2][1],s22=tr[p].s[2][2];tr[p].s[1][1]=(s11*c[0][0]+s12*c[1][0])%MOD;tr[p].s[1][2]=(s11*c[0][1]+s12*c[1][1])%MOD;tr[p].s[2][1]=(s21*c[0][0]+s22*c[1][0])%MOD;tr[p].s[2][2]=(s21*c[0][1]+s22*c[1][1])%MOD;}else{push(p);int mid=(tr[p].l+tr[p].r)/2;if(l<=mid)change(p*2,l,r,x);if(r>mid)change(p*2+1,l,r,x);up(p);}}int main(){int n,m;scanf("%d%d",&n,&m);int i;for(i=1;i<=n;i++)scanf("%d",&a[i]);build(1,1,n);int x,s,t;for(i=1;i<=m;i++){scanf("%d",&x);if(x==2){scanf("%d%d",&s,&t);printf("%I64d\n",query(1,s,t));}else{scanf("%d%d%d",&s,&t,&x);c[0][0]=0;c[0][1]=1;c[1][0]=1;c[1][1]=1;c=c^x;change(1,s,t,x);}}return 0;}


0 0
原创粉丝点击