#include #include #include #include #include using namespace std; typedef long long lint; typedef vectorvi; typedef pairpii; typedef pairpll; #define rep(i,n)for(int i=0;i<(int)(n);++i) const lint mo=1e9+7; const int N=1000000; const int A=1000; const int B=N/A; lint a[N]; lint asum[A]; lint u[A],v[A]; lint tap[A]; pll phi[N]; pll phiacc[N+1]; lint madd(lint a,lint b){ lint c=a+b; return c>=mo?c-mo:c; } pll add(pll a,pll b){ return pll((a.first+b.first)%mo,(a.second+b.second)%mo); } pll mul(pll a,pll b){ lint x=a.first*b.first+5*a.second*b.second; lint y=a.first*b.second+a.second*b.first; return pll(x%mo,y%mo); } void init(){ pll p((mo+1)/2,(mo+1)/2); pll c(1,0); rep(i,N){ phi[i]=c; phiacc[i+1]=add(phiacc[i],phi[i]); c=mul(c,p); } } void red(int k){ if(k>=A)return; lint tmp=0; rep(i,B){ int idx=k*B+i; a[idx]=u[k]*a[idx]+v[k]+2*tap[k]*phi[idx].second; a[idx]%=mo; tmp=madd(tmp,a[idx]); } u[k]=1; v[k]=0; tap[k]=0; asum[k]=tmp; } void upd_n_sx_plus_t(int l,int r,int s,int t){ assert(r<=l/B*B+B); if(l>=r)return; red(l/B); lint tmp=asum[l/B]; for(int i=l;irb){ upd_n_sx_plus_t(l,r,s,t); return; } upd_n_sx_plus_t(l,B*lb,s,t); upd_n_sx_plus_t(B*rb,r,s,t); for(int i=lb;i=r)return; red(l/B); lint tmp=asum[l/B]; for(int i=l;irb){ upd_n_fib(l,r,k); return; } upd_n_fib(l,B*lb,k); upd_n_fib(B*rb,r,k); for(int i=lb;i=r)return 0; red(l/B); lint ans=0; for(int i=l;irb){ return calc_n(l,r); } lint ans=0; ans=calc_n(l,B*lb); ans=calc_n(B*rb,r); for(int i=lb;i=0); assert(kind<=4); assert(l=0); assert(r<=n); assert(k>=0); assert(k<=1e9); switch(kind){ case 0: printf("%lld\n",k*calc(l,r)%mo); break; case 1: upd_sx_plus_t(l,r,0,k); break; case 2: upd_sx_plus_t(l,r,1,k); break; case 3: upd_sx_plus_t(l,r,k,0); break; case 4: upd_fib(l,r,k); break; } } }