链接:https://ac.nowcoder.com/acm/contest/874/B
来源:牛客网
题目描述
HRY is a pupil. He has just learned about Fibonacci sequence recently, and he made some new sequences :
fic(n)=∑ni=1fib(i)fic(n)=∑i=1nfib(i)
fid(n)=∑ni=1fic(i)fid(n)=∑i=1nfic(i)
fib(i) means the ith element in the Fibonacci sequence :
fib(1)=fib(2)=1,fib(i)=fib(i−1)+fib(i−2),i≥3fib(1)=fib(2)=1,fib(i)=fib(i−1)+fib(i−2),i≥3
At first this problem is to calculate fid(n), but that is too easy. So after discussing with 10256, they changed the problem:
Given a positive integer array a1,a2,...,ana1,a2,...,an, perform the following two types of operations:
1. Given l,r,x, for all l≤i≤rl≤i≤r, execute ai=ai+xai=ai+x.
2. Given l,r, calculate(∑ri=lfid(ai))%100000007(∑i=lrfid(ai))%100000007.
输入描述:
The first line of the input contains an integer n, indicating the length of the array.
The second line contains n positive integers separated by spaces, indicating a1,a2,...,an−1,ana1,a2,...,an−1,an.
The third line contains an integer Q, indicating the number of operations.
For the next Q lines, it is either 1 l r x1 l r x, indicating the first type of operation, or 2 l r2 l r, indicating the second type of operation.
All values in input are integers.
1≤n,Q≤100000,1≤ai,x≤109,1≤l≤r≤n.1≤n,Q≤100000,1≤ai,x≤109,1≤l≤r≤n.
输出描述:
For each operation of second type, output(∑ri=lfid(ai))%100000007(∑i=lrfid(ai))%100000007.
示例1
输入
复制
3 1 2 3 6 2 1 3 1 1 3 1 2 1 3 1 1 1 2 1 2 2 3 2 1 3
输出
复制
11 24 74
注意取模是1e8+7...很坑
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
const int mod=1e8+7;
int n,q;
struct matrix
{
ll a[4][4];
matrix(){memset(a,0,sizeof a);}
void init()
{
memset(a,0,sizeof a);
for(int i=0;i<4;i++)a[i][i]=1;
}
void solve(){a[0][0]=a[0][1]=a[1][0]=a[2][0]=a[2][2]=a[3][2]=a[3][3]=1;}
matrix operator *(const matrix &b)const
{
matrix res;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
for(int k=0;k<4;k++)
res.a[i][j]=(res.a[i][j]+a[i][k]*b.a[k][j])%mod;
return res;
}
matrix operator +(const matrix &b)const
{
matrix res;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
res.a[i][j]=(a[i][j]+b.a[i][j])%mod;
return res;
}
}d[maxn<<2],b[maxn<<2],base;
void build(int l,int r,int p)
{
b[p].init();
if(l==r) {d[p].init();return ;}
int m=(l+r)>>1;build(l,m,p<<1);build(m+1,r,p<<1|1);
d[p]=d[p<<1]+d[p<<1|1];
}
void update(int l,int r,int s,int t,int p,matrix c)
{
if(l==s&&t==r){d[p]=d[p]*c,b[p]=b[p]*c;return;}
int m=(s+t)>>1;
if(r<=m)update(l,r,s,m,p<<1,c);
else if(m<l)update(l,r,m+1,t,p<<1|1,c);
else update(l,m,s,m,p<<1,c),update(m+1,r,m+1,t,p<<1|1,c);
d[p]=(d[p<<1]+d[p<<1|1])*b[p];
}
matrix query(int l,int r,int s,int t,int p)
{
if(l==s&&t==r)return d[p];
int m=(s+t)>>1;
if(r<=m) return query(l,r,s,m,p<<1)*b[p];
else if(m<l) return query(l,r,m+1,t,p<<1|1)*b[p];
else return b[p]*(query(l,m,s,m,p<<1)+query(m+1,r,m+1,t,p<<1|1));
}
matrix fpow(matrix a,ll b)
{
matrix res;res.init();
while(b)
{
if(b&1)res=res*a;
a=a*a;
b>>=1;
}
return res;
}
int main()
{
matrix base;base.solve();
scanf("%d",&n);build(1,n,1);
for(int i=1;i<=n;i++){int x;scanf("%d",&x);update(i,i,1,n,1,fpow(base,x+2));}
scanf("%d",&q);
while(q--)
{
int p;scanf("%d",&p);
if(p==1){int l,r,x; scanf("%d%d%d",&l,&r,&x),update(l,r,1,n,1,fpow(base,x));}
if(p==2){int l,r;scanf("%d%d",&l,&r),printf("%lld\n",query(l,r,1,n,1).a[3][1]);}
}
return 0;
}