CF718C Sasha and Array(线段树维护矩阵)

Posted xu-daxia

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF718C Sasha and Array(线段树维护矩阵)相关的知识,希望对你有一定的参考价值。

技术分享图片

题解

(不会矩阵加速的先去学矩阵加速)

反正我想不到线段树维护矩阵。我太菜了。

我们在线段树上维护一个区间的斐波那契的列矩阵的和。

然后询问时提取每个符合题意列矩阵的答案项(不是列矩阵存了两项吗,一个是当前项,一个是用来递推的)

因为矩阵乘有结合律所以区间加这个操作就直接区间乘变换矩阵的x次方就行。

然后记得开long long

技术分享图片
  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<algorithm>
  5 #include<cmath>
  6 using namespace std;
  7 const long long mod=1e9+7;
  8 const long long N=100100;
  9 long long n,m;
 10 struct jz{
 11     long long a[3][3];
 12 }e,h,be,f[N],ma;
 13 struct tree{
 14     long long l,r;
 15     jz sum,lazy;
 16 }tr[N*5];
 17 jz jzc(jz a,jz b,jz c){
 18     for(long long i=1;i<=2;i++)
 19         for(long long j=1;j<=2;j++)
 20             for(long long k=1;k<=2;k++){
 21                 c.a[i][j]+=a.a[i][k]*b.a[k][j];
 22                 c.a[i][j]%=mod; 
 23             }
 24     return c;
 25 }
 26 jz ksm(long long b,jz x){
 27     jz ans;
 28     ans=ma;
 29     while(b){
 30         if(b&1){
 31             ans=jzc(ans,x,h);
 32         }
 33         b>>=1;
 34         x=jzc(x,x,h);
 35     }
 36     return ans;
 37 }
 38 void update(long long now){
 39     tr[now].sum.a[1][1]=(tr[now*2].sum.a[1][1]+tr[now*2+1].sum.a[1][1])%mod;
 40     tr[now].sum.a[1][2]=(tr[now*2].sum.a[1][2]+tr[now*2+1].sum.a[1][2])%mod;
 41 }
 42 void build(long long l,long long r,long long now){
 43     tr[now].l=l;tr[now].r=r;tr[now].lazy=ma;
 44     if(l==r){
 45         tr[now].sum=f[l];
 46         return;
 47     }
 48     long long mid=(l+r)>>1;
 49     build(l,mid,now*2);
 50     build(mid+1,r,now*2+1);
 51     update(now);
 52 }
 53 bool pd(jz a,jz b){
 54     for(long long i=1;i<=2;i++)
 55         for(long long j=1;j<=2;j++)
 56             if(a.a[i][j]!=b.a[i][j])return false;
 57     return true;
 58 }
 59 void pushdown(long long now){
 60     if(pd(tr[now].lazy,ma))return;
 61     tr[now*2].sum=jzc(tr[now*2].sum,tr[now].lazy,h);
 62     tr[now*2+1].sum=jzc(tr[now*2+1].sum,tr[now].lazy,h);
 63     tr[now*2].lazy=jzc(tr[now*2].lazy,tr[now].lazy,h);
 64     tr[now*2+1].lazy=jzc(tr[now*2+1].lazy,tr[now].lazy,h);
 65     tr[now].lazy=ma;
 66 }
 67 void add(long long l,long long r,long long now,jz x){
 68     pushdown(now);
 69     if(tr[now].l==l&&tr[now].r==r){
 70         tr[now].sum=jzc(tr[now].sum,x,h);
 71         tr[now].lazy=x;
 72         return;
 73     }
 74     long long mid=(tr[now].l+tr[now].r)>>1;
 75     if(l>mid)add(l,r,now*2+1,x);
 76     else if(r<=mid)add(l,r,now*2,x);
 77     else{
 78         add(l,mid,now*2,x);
 79         add(mid+1,r,now*2+1,x); 
 80     }
 81     update(now);
 82 }
 83 long long query(long long l,long long r,long long now){
 84     pushdown(now);
 85     if(tr[now].l==l&&tr[now].r==r){
 86         return tr[now].sum.a[1][2];
 87     }
 88     long long mid=(tr[now].l+tr[now].r)>>1;
 89     if(l>mid)return query(l,r,now*2+1);
 90     else if(r<=mid)return query(l,r,now*2);
 91     else return (query(l,mid,now*2)+query(mid+1,r,now*2+1))%mod;
 92 }
 93 int main(){
 94     scanf("%lld%lld",&n,&m);
 95     e.a[1][1]=0;e.a[1][2]=e.a[2][1]=e.a[2][2]=1;
 96     be.a[1][1]=0;be.a[1][2]=1;
 97     for(long long i=1;i<=2;i++)
 98         for(long long j=1;j<=2;j++)
 99             if(i==j)ma.a[i][j]=1;
100             else ma.a[i][j]=0;
101     for(long long i=1;i<=n;i++){
102         long long x;
103         scanf("%lld",&x);
104         if(x==1)f[i]=be;
105         else f[i]=jzc(be,ksm(x-1,e),h); 
106     }
107     build(1,n,1);
108     for(long long i=1;i<=m;i++){
109         long long k;
110         scanf("%lld",&k);
111         if(k==1){
112             long long l,r,x;
113             scanf("%lld%lld%lld",&l,&r,&x);
114             add(l,r,1,ksm(x,e));
115         }
116         else{
117             long long l,r;
118             scanf("%lld%lld",&l,&r);
119             printf("%lld
",query(l,r,1));
120         }
121     }
122     return 0;
123 }
View Code

 

以上是关于CF718C Sasha and Array(线段树维护矩阵)的主要内容,如果未能解决你的问题,请参考以下文章

CF718C Sasha and Array(线段树维护矩阵)

题解 CF718C Sasha and Array

题解 CF718C Sasha and Array

718C Sasha and Array

CodeForces 718C Sasha and Array

CF719E. Sasha and Array [线段树维护矩阵]