斐波那契数列
此题原题不记得题号多少了。。。。。粘进SDOJ里面为了搞笑改了名字,又直接粘过来了。
没想到这个博客竟然有人看这个题解提出原题的问题了,本以为没有人,,,,,,,,emmm好吧实在记不得原题了就凭印象改成George吧
发现我校内OJ里干的这种事挺多的,emmm,我的名字搞笑出来的题目以后还是不要放出来了。
还是很感谢评论区指出错误
George最近研究数列研究得入迷啦!
现在有一个斐波拉契数列(f[1]=f[2]=1,对于n>2有f[n]=f[n-1]+f[n-2]),
但是斐波拉契数列太简单啦,于是ZYH把它改成了斐波拉契的前缀和的数列{Si}(S[1]=1,对于n>1,有S[n]=S[n-1]+f[n]),接下来ZYH要在{Si}数列上面做一些操作。
1.修改: 将数列中下标在[l,r]区间内的数加上v
2.查询:询问此时数列第k项对1000000007取模后是多少。
你能帮他解决这两个操作吗?
对于 10%的数据有 n ≤10^3, l ≤ r ≤ 10^3 , k≤10^3 , v≤10^3
对于 30%的数据有 n ≤10^5 , l ≤ r ≤ 10^6 , k≤10^6 , v≤10^6
对于 60%的数据有 n ≤10^5 , l ≤ r ≤ 10^6 , k≤10^9 , v≤10^9
对于 100%的数据有 n ≤10^5 , l ≤ r ≤ 10^9 , k≤10^9 , v≤10^9
source:光华测试day1t3
矩阵快速幂就不说了,大家都会,这里粘一个板子参考
1 #include<cstdio> 2 #include<cmath>//pow函数,其实没啥用 3 using namespace std; 4 5 int n;long long k; 6 const int N=pow(10,9)+7; 7 struct node{long long a[105][105];}; 8 node shu,ans,mp; 9 //shu是输入的矩阵,ans是所求答案 10 node matrix(node x,node y){ 11 for(int i=1;i<=n;i++) 12 for(int j=1;j<=n;j++){ 13 mp.a[i][j]=0; 14 for(int p=1;p<=n;p++) 15 mp.a[i][j]=(mp.a[i][j]+x.a[i][p] * y.a[p][j])%N; 16 //矩阵乘法 17 } 18 return mp; 19 } 20 21 int work(long long k){//矩阵快速幂 22 while(k){ 23 if(k&1) 24 ans=matrix(ans,shu); 25 k>>=1; 26 shu=matrix(shu,shu); 27 } 28 } 29 30 int main(){ 31 scanf("%d%lld",&n,&k); 32 for(int i=1;i<=n;i++){ 33 for(int j=1;j<=n;j++) 34 scanf("%d",&shu.a[i][j]); 35 ans.a[i][i]=1;//任何一个矩阵乘以单位矩阵,其值等于本身; 36 } 37 38 work(k); 39 40 for(int i=1;i<=n;i++){ 41 for(int j=1;j<=n;j++) 42 printf("%d ",ans.a[i][j]); 43 printf("\n"); 44 } 45 return 0; 46 }
线段树几乎是板子
但是数据很大,显然不能硬来
看到询问很小于是离散化
排序之后请按13579进行映射,因为中间留的偶数是给那些在这些区间内被包含(不含两边)的数
那么离散化之后就很小了,直接线段树乱搞就行了
其实我没写std。。。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 #define LL long long 6 using namespace std; 7 const int MAXN=1000001; 8 const LL MOD=1e9+7; 9 int n,m; 10 LL tz; 11 int tx,ty; 12 struct NODE{ 13 int l,r; 14 LL val; 15 NODE() 16 { 17 l=r=0;val=0; 18 } 19 }tr[MAXN*4]; 20 int num=0; 21 22 LL mod(LL x) 23 { 24 return x%MOD; 25 } 26 27 void Pushup(int x) 28 { 29 tr[x].val=mod(tr[tr[x].l].val+tr[tr[x].r].val); 30 } 31 32 void Update(int x,int L,int R,int aim,LL v) 33 { 34 if(L==R) 35 { 36 tr[x].val+=v; 37 if(tr[x].val>=MOD)tr[x].val-=MOD; 38 return ; 39 } 40 int mid=(L+R)/2; 41 42 if(aim<=mid) 43 { 44 if(!tr[x].l) 45 { 46 tr[x].l=++num; 47 } 48 Update(tr[x].l,L,mid,aim,v); 49 } 50 else 51 { 52 if(!tr[x].r) 53 { 54 tr[x].r=++num; 55 } 56 Update(tr[x].r,mid+1,R,aim,v); 57 } 58 Pushup(x); 59 } 60 61 LL Query(int x,int L,int R,int al,int ar) 62 { 63 if(R<al||L>ar)return 0; 64 if(al<=L&&R<=ar) 65 { 66 return tr[x].val; 67 } 68 int mid=(L+R)/2; 69 return mod(Query(tr[x].l,L,mid,al,ar)+Query(tr[x].r,mid+1,R,al,ar)); 70 } 71 72 struct Matrix{ 73 LL a[4][4]; 74 75 void QL() 76 { 77 for(int i=1;i<=3;i++) 78 for(int j=1;j<=3;j++) 79 a[i][j]=0; 80 } 81 82 void DW() 83 { 84 QL(); 85 for(int i=1;i<=3;i++)a[i][i]=1ll; 86 } 87 88 void init() 89 { 90 QL(); 91 a[1][1]=1;a[1][2]=1;a[1][3]=1; 92 a[2][1]=0;a[2][2]=1;a[2][3]=1; 93 a[3][1]=0;a[3][2]=1;a[3][3]=0; 94 } 95 }p,l[1<<16],r[1<<16]; 96 97 Matrix mul(Matrix x,Matrix y) 98 { 99 Matrix z; 100 z.QL(); 101 for(int i=1;i<=3;i++) 102 { 103 for(int j=1;j<=3;j++) 104 { 105 for(int k=1;k<=3;k++) 106 { 107 z.a[i][j]=mod(z.a[i][j]+x.a[i][k]*y.a[k][j]); 108 } 109 } 110 } 111 return z; 112 } 113 114 int main() 115 { 116 117 // freopen("george9.in","r",stdin); 118 // freopen("george9.out","w",stdout); 119 120 r[0].DW(); 121 r[1].init(); 122 for(int i=2;i<(1<<16);i++) 123 { 124 r[i]=mul(r[1],r[i-1]); 125 } 126 127 l[0].DW(); 128 l[1]=mul(r[(1<<16)-1],r[1]); 129 130 for(int i=2;i<(1<<16);i++) 131 { 132 l[i]=mul(l[1],l[i-1]); 133 } 134 135 scanf("%d",&n); 136 num++; 137 for(int i=1;i<=n;i++) 138 { 139 scanf("%d",&tx); 140 if(tx==1) 141 { 142 scanf("%d%d%lld",&tx,&ty,&tz); 143 Update(1,1,1000000001,tx,tz); 144 Update(1,1,1000000001,ty+1,-tz); 145 } 146 else 147 { 148 scanf("%d",&tx); 149 ty=tx-2; 150 LL ans=0; 151 if(tx<=2)ans=((LL)tx); 152 else 153 { 154 p=mul(l[ty>>16],r[ty-((ty>>16)<<16)]); 155 ans=mod(2*p.a[1][1]+p.a[1][2]+p.a[1][3]); 156 } 157 158 printf("%lld\n",mod(mod(ans+Query(1,1,1000000001,1,tx))+MOD)); 159 } 160 } 161 return 0; 162 }